Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« : 30-01-2004 10:03 » |
|
не знаю, насколько мой вопрос относится к базам данных. может, и относится... вообще, он про FoxPro. интересное явление наблюдается. был написан код в FoxPro 2.6. процедура одна. я ее включала как метод одного из классов в VFP 6.0. точ в точь то же самый код. так вот в VFP 6.0 этот код работает в среднем раз в пять дольше, чем в FP 2.6. замеряли с секундомером. как такое может получаться?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #1 : 30-01-2004 11:38 » |
|
А проблемный код нашли? Можешь его привести здесь? Попробую в понедельник показать человеку, который давно на фоксе программирует - может чего подскажет. Только не забудь обернуть тегом code, а то нечитабельно будет.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #2 : 30-01-2004 13:30 » |
|
вообще-то, он достаточно громоздкий. и вряд ли, в нем можно быстро разобраться... запустить его уж точно не получиться. если только по виду можно будет что-то сказать... я думала, может, что-то принципиальное мешает ему выполняться. Может, то, что таблицы в Базу данных не собраны.. а может, VFP память, как-то иначе использует, не так, как FoxPro 2.6... вот он, код: Parameters NK_Un, NK_SUN, NK_SDate, NK_EDate
NK_SD = NK_SDate NK_ED = NK_EDate SNK_Un = NK_Un SNK_SUN = NK_SUn
select NKart SD = NK_SD - day(NK_SD) + 1 ED = gomonth(NK_ED - day(NK_ED) + 1, 1) - 1 do while SD <= ED append blank replace Uniqnum with NK_UN,; RMonth with SD SD = gomonth(SD,1) enddo
select Romoney go top
if seek(NK_UN, 'RB866', 4) UNArrSize = 1 do while .T. if RB866->SeekDn > 0 if seek(RB866->SeekDn, 'RB866', 4) UNArrSize = UNArrSize + 1 loop endif endif exit enddo
dimension UNArr[UNArrSize] UNArr = 0 for UnCount = 1 to UNArrSize UNArr[UNCount] = RB866->UniqNum SUp = RB866->SeekUp if SUp > 0 .and. seek(SUp, 'RB866', 4) loop endif exit endfor else return endif
select NKart go top scan N_RMonth = NKart.RMonth
for UnCount = 1 to UNArrSize NK_UN = UNArr[UNCount] NK_SUN = padl(alltrim(str(UNArr[UNCount])), 7, '0')
if !seek(NK_SUN, 'RoMoney') loop endif
select RoMoney set order to 2 if seek(NK_SUN + str(99999999 - val(dtos(N_RMonth)), 8), 'RoMoney') && RoMoney.PMonth select RoMoney scan rest; for RoMoney.RC > 0 .and. !empty(DocNo) .and. !empty(DocDate); .and. RoMoney.PMonth = N_RMonth; while RoMoney.Uniqnum = NK_UN .and. RoMoney.PMonth = N_RMonth
=This.AddRecs() endscan endif endfor &&for UnCount = 1 to UNArrSize
select TMoney replace all TMoney.Summa with round(Summa, _MRound) go top TOTAL TO (_TotFile) ON NUCode FIELDS Summa
select 0 use (_TotFile) alias TFile exclusive
select KLNKrt go top FList = '' scan for KLNKrt.F_User .and. !eof('KLNKrtS') .and. !empty(KLNKrt.F_Func) .and. eof('KLNKrtD1') VarName = alltrim(Field_Name) VarSumma = 0 FList = FList + iif(!empty(FList), ",", "") + alltrim(Field_Name) select KLNKrtS scan rest for KLxCode == KLNKrt.F_klx .and. at(Scode, alltrim(KLNKrt.F_Func)) > 0 SNU = 0 if !empty(KLCodeNU) select TFile sum Summa to SNU for at(NUCode, alltrim(KLNKrtS.KLCodeNU)) > 0 select KLNKrtS endif VarSumma = VarSumma + SNU endscan &VarName = VarSumma select NKart gather memvar fields &VarName if !empty(KLNKrt.F_expr) ErrOk = .F. on error ErrOk = .T. Expr = alltrim(KLNKrt.F_expr) S = evaluate(Expr) on error &_lcOldError if ErrOk VarSumma = 0 else VarSumma = S endif &VarName = VarSumma select NKart gather memvar fields &VarName endif select KLNKrt endscan
* Кусок, который особенно тормозит в VFP и выполняется мгновенно в 2.6 select TMoney set order to 2 go top m.RMonth = N_RMonth select KLNKrtD go top scan for !eof('KLNKrtS') select TMoney go top SNU = 0 sum Summa to SNU for at(NUCode, alltrim(KLNKrtS.KLCodeNU)) > 0 ; and at(T_Work,alltrim(KLNKrtS.SCat)) > 0 ; and at(Zvan,upper(KLNKrtS.SZvan)) > 0 select NKartD SNU_All = 0 go top sum Summa to SNU_All for NKartD.Str_ind = KLNKrtD.Str_ind ; while NKartD.RMonth < N_RMonth select NKartD if !seek(strtran(str(NK_UN,7), ' ', '0') + dtos(N_RMonth) ; + strtran(str(KLNKrtD.Str_Ind, 2), ' ', '0')) append blank replace UniqNum with NK_UN, ; RMonth with N_RMonth, ; Str_ind with KLNKrtD.Str_ind endif
SMnth = 'SM_' + alltrim(str(Str_ind, 2)) &SMnth = SNU SYear = 'SG_' + alltrim(str(Str_ind, 2)) &SYear = SNU_All + SNU
if !empty(alltrim(KLNKrtD.Expr)) VarList = '' select Prochie set relation off into Docum
select Docum set relation to upper(NUProc) into KLNKrtP go top scan for at(Docum.NuCode,alltrim(KLNKrtS.KLCodeNU)) > 0 and !eof('KLNKrtP') if seek(NK_SUN + Docum.Doc, 'Prochie') select Prochie locate rest for Doc = Docum.Doc ; .and. S_Date <= gomonth(m.RMonth - day(m.RMonth) + 1, 1) - 1 ; .and. year(S_Date)=year(N_RMonth); while UniqNum = NK_UN if found() scatter memvar select KLNKrtP scan rest while upper(NUproc) = upper(Docum.Nuproc) PVar = alltrim(KLNKrtP.P_varN) MVar = alltrim(KLNKrtP.P_pfield) &PVar = &MVar VarList = VarList + iif(empty(VarList), "", ",") + PVar endscan endif endif select Docum endscan
select Docum set relation off into KLNKrtP
select Prochie set relation to Doc into Docum additive =seek(NK_SUN, 'Prochie')
StrExpr = alltrim(KLNKrtD.Expr) ErrOk = .F. on error ErrOk = .T. SumExpr = eval(StrExpr) on error &_lcOldError if ErrOk SumExpr = 0 endif
SNU = SumExpr if !empty(VarList) release &VarList endif select NKartD replace Summa with Summa + SNU, ; Summa_All with SNU_All + SNU &&Summa else select NKartD replace Summa with Summa + SNU, ; Summa_All with SNU_All + SNU &&Summa endif
&SMnth = NKartD.Summa &SYear = NKartD.Summa_All
select KLNKrtD endscan &&®ЇаҐ¤Ґ«ҐЁҐ ¤®Ї.Ёд.
* <end> Кусок ...
select KLNKrt go top scan for KLNKrt.F_User .and. !eof('KLNKrtS') .and. !empty(KLNKrt.F_Func); .and. !eof('KLNKrtD1') VarName = alltrim(Field_Name) VarSumma = 0 select KLNKrtS scan rest for KLxCode == KLNKrt.F_klx .and. at(Scode,alltrim(KLNKrt.F_Func))>0 SeekC = SNK_SUN + dtos(N_RMonth) + STRTRAN(STR(KLNKrtD1.STR_IND, 2), " ", "0") SNU = iif(seek(SeekC, 'NKartD'), NKartD.Summa, 0) VarSumma = VarSumma + SNU endscan &VarName = VarSumma select NKart gather memvar fields &VarName if !empty(KLNKrt.F_expr) ErrOk = .F. on error ErrOk = .T. Expr = alltrim(KLNKrt.F_expr) S = evaluate(Expr) on error &_lcOldError if ErrOk VarSumma = 0 else VarSumma = S endif &VarName = VarSumma select NKart gather memvar fields &VarName endif select KLNKrt endscan
select TMoney set order to 1 zap
select TFile zap use in TFile
select NKart
endscan
if set('debug') == 'ON' on key label F12 endif
return && FillNKrt
|
|
« Последнее редактирование: 23-11-2007 20:59 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #3 : 02-02-2004 09:50 » |
|
Falsehood, по коду трудно сказать. Есть несколько моментов: возможно, нехватает памяти и, возможно, процессорное время съедает какая-нибудь другая программа на той же машине. Попробуй расставить по программе строку "?second()" (до и после каждого цикла) и поимешь какой участок работает дольше.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #4 : 02-02-2004 10:32 » |
|
вычислили, какой участок долго работает (я в коде его отметила. наверное, не очень заметно). точь в точь в одинаковых усливиях под ДОСовсиким FoxPro и по VFP этот код не запустить, но разница во времени слишком большая, чтобы дело было в каком-то приложении. причем запускали по несколько раз в разных условиях. результат приблизительно один и тот же... но все равно, спасибо
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 02-02-2004 11:26 » |
|
Комментария видел. Спец говорит, что VFP очень критичен к недостатку памяти.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #6 : 03-02-2004 12:28 » |
|
RXL, спасибо. будем думать в этом направлении
|
|
|
Записан
|
|
|
|
Joys
Гость
|
|
« Ответ #7 : 24-02-2004 20:32 » |
|
RXL, спасибо. будем думать в этом направлении В думах могут помочь на http://forum.foxclub.ruПричем довольно быстро
|
|
|
Записан
|
|
|
|
Fireworm
Гость
|
|
« Ответ #8 : 25-02-2004 07:37 » |
|
Проверьте расстановку индексов, может в этом дело?
|
|
|
Записан
|
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #9 : 25-02-2004 12:07 » |
|
Joys, спасибо. посмотрю.
Fireworm, индексы расставлены точь в точь, как в программы, которая работает под FoxPro 2.6.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #10 : 25-02-2004 20:24 » |
|
Falsehood, если пересказать дословно, то что мне говорил спец, то просто надо экспериментально найти проблему. Код я у тебя спросил заранее, дабы не задавать ему голословный вопрос, а он сказал что, для того чтобы найти причину, нужно иметь и базу (знать формат, индексы, размер). Но основная предпологаемая причина - нехватка памяти. Фокс очень быстро работает с базами малого объема, а с большими - трудно предсказуемо. Он у нас написал ряд программ на фоксе и одна из них (обработка биллинговых данных приличных размеров - 10..20Мб за сутки) работает с переменной скоростью - разница в скорости раз в 100! Перезагрузка винды помогает ускорить процесс.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #11 : 26-02-2004 09:36 » |
|
RXL, мы поэксперементировали и выяснили, что тормозит цикл сканирования одной таблицы. в ней где-то 300 записей. это аж 300 с лишним килобайт сканировалась вся таблица, а требовались из нее всего 7 записей. мы стали выбирать эти 7 записей зарание. процедура стала выполняться по времени столько же, сколько и в FP 2.6 - 5-6 секунд. но в FP 2.6 после такой оптимизации она стала выполняться 1-2 секунды мы бы, наверно, приняли такую скорость работы VFP как должное, если бы не было возможности сравнить с FP 2.6. непонятно, почему такая разница... кстати, не посоветуете прогу какую-нибудь под Win98, чтобы она показывала память используемую каждым процессом, наподобие Task Manager-a в WinXP? что-то мне все какие-то бестолковые попадаются...
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #12 : 26-02-2004 11:25 » |
|
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #13 : 27-02-2004 10:19 » |
|
RXL, спасибо. посмотрю
|
|
|
Записан
|
|
|
|
AlxIV
Гость
|
|
« Ответ #14 : 28-02-2004 03:30 » |
|
По поводу разницы между VFP и FP2.6 не могу сказать, но данный кусок точно можно несколько оптимизировать. Например Go top перед командами locate, scan и т.п. c опцией for (когда нет while и rest) не нужен и иногда сильно тормозит. особенно жто заметно при использовании фильтров. И еще, если можно, лучше как можно меньше использовать макроподстановку. А также вместо команд append blank и последующего replace можно использовать insert into при этом не обязательно переходить в ту область, где находится база. Проверку по бустродействию можно делать так: сделать цикл побольше и засечь сколько выполняется та или иная последоваетльность.
|
|
|
Записан
|
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #15 : 01-03-2004 17:24 » |
|
RXL, TaskInfo не показывает память, используемую FP2.6 только процессорное время. AlxIV, понятно, что надо оптимизировать... но хотелось же так, CTRL+C, CTRL+V не получилось
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 01-03-2004 21:17 » |
|
Falsehood, ткни в его процесс, а в правом нижнем окне выбери закладку General. Там вся используемая память расписана.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Falsehood
Молодой специалист
Offline
Пол:
не может быть
|
|
« Ответ #17 : 02-03-2004 10:45 » |
|
RXL, для его процесса в правом нижнем окне все вкладки пустые.
|
|
|
Записан
|
|
|
|
|