Сравнение циклов | |
---|---|
Foxtrot Автор Сообщений: 3408 Откуда: Куда: Дата регистрации: 25.04.2003 |
Итак, имеем два разных по "размеру" вложенных цикла:
первый допустим от 0 до 123, а второй от 0 до 123456789 внимание вопрос: который из двух вариантов отработает быстрее другого? вариант 1:
------------------ Мойте ноги, моя ноги вы моете и руки |
Re: Сравнение циклов | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Канат!
Ты и не представляешь насколько "тонкий" предмет затронул Очень многое зависит от порядка создания переменных - и вообще от "внешних факторов" - даже от того как ты замеряешь скорость исполнения этого куска кода А "в общем" принципиальной разницы нету - будет быстрее, если доступ к переменной "большего" цикла будет быстрее и медленнее в противном случае. А порядок следования циклов будет не столь важен. Банально сравни:
------------------ WBR, Igor |
Re: Сравнение циклов | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Опа, я отказываюсь это понимать, здесь что важен принцип FIFO/LIFO при создании переменных - неожиданно.
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: Сравнение циклов | |
---|---|
matod Сообщений: 3062 Откуда: Иркутск Дата регистрации: 31.10.2001 |
Дык. Интерпретатор все-таки. Переменную объявили - ее имя в табличку вмесие со ссылкой на данные. Надо значение - ищем по табличке (бинарным поиском, надеюсь ). Находим имя, затем по ссылке данные.
Компилятор имя вообще не стал бы хранить, поэтому там разница была бы абсолютно несущественна. Это плата за "динамический" код - макроподстановки, ExecScript() и т.п. |
Re: Сравнение циклов | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi matod!
Ну да Из этой же оперы сравнение производительности доступа к переменной через var против m.var - там на результат влияет (что вполне логично если слегка поразмыслить) количество полей в текущем курсоре. А что касается компилятора - то тоже не всё так просто - ведь во время исполнения данные находятся в регистрах процессора а не в памяти - и соответственно если свободного регистра нет - т.е. приходится данные помещать в память (обычно локальные переменные в стеке сидят) - производительность заметно падает. ------------------ WBR, Igor |
Re: Сравнение циклов | |
---|---|
matod Сообщений: 3062 Откуда: Иркутск Дата регистрации: 31.10.2001 |
Цитата:Угу. Только это большое счастье занять регистр процессора под переменную. Ведь переменных много, а регистров нет. Производительность падает, но это все равно лучше, поскольку компилятор заменяет обращение к переменной работой с физическим адресом, без всяких циклов поиска... Можно предположить также что на скорость выполнения будут влиять и другие команды, формирующие списки в памяти - последовательность файлов в SET PATH, SET CLASSLIB и их количество, а также команды в которых имеются альтернативные способы поиска объектов, например do или вызовы UDF - быстрее будут выполнятся те, которые в списке поиска команды стоят раньше. |
Re: Сравнение циклов | |
---|---|
leonid Сообщений: 3204 Откуда: Рига Дата регистрации: 03.02.2006 |
Мне кажется, что кроме "тонкой" компоненты здесь есть и более "грубый" подтекст. Поскольку фокс - интерпретатор, то при исполнении кода
оператор FOR y=0 TO 123 выполнится 1 раз, оператор FOR i=0 TO 1234567 выполнится 123 раза, первый ENDFOR выполнится 123*1234567 раз, и последний ENDFOR выполнится 123 раза. А при выполнении кода
оператор FOR y=0 TO 1234567 выполнится 1 раз, оператор FOR i=0 TO 123 выполнится 1234567 раза, первый ENDFOR выполнится 123*1234567 раз, и последний ENDFOR выполнится 1234567 раза. Т.е. основная разница по времени будет достигаться на втором операторе FOR и на последнем ENDFOR. Это особенно заметно, если 123 заменить на 1. |
Re: Сравнение циклов | |
---|---|
Foxtrot Автор Сообщений: 3408 Откуда: Куда: Дата регистрации: 25.04.2003 |
ответ верный, все дело в количестве выполнений команд
а насчет переменных скажу лишь одно, поиск переменных в памяти тут совсем ни причем вспомним классика "горе от ума" ------------------ Мойте ноги, моя ноги вы моете и руки |
Re: Сравнение циклов | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi leonid & Канат!
Банальное сравнение "количества выполнений команды" не даёт адекватного представления о скорости работы программы. Даже для машинных инструкций, время исполнения разных команд может отличаться в разы! Что уж говорить про интерпретатор, когда каждая инструкция это по сути вызов процедуры - ты же не будешь спорить что вызвать 1000 раз "быструю" процедуру будет эффективнее чем 10 раз вызвать "медленную" (даже если это одна и та же процедура, просто с разными параметрами). А тут как раз похожая ситуация - время исполнения одной и той же "внутренней процедуры" существенно различается. Что есть FOR...ENDFOR? - создание переменной, если её не было (1 раз) - присвоение начального значения (1 раз) - проверка на выполнение граничного условия (много раз) При этом самое "тяжелое" действие связано именно с доступом к переменной цикла - поэтому время этого доступа и будет определяющим. Конечно "присвоение" значения это тоже небыстрый процесс (т.е. разница конечно будет), однако не думаю что в общем времени исполнения тестового кода это занимает заметный процент. Особенно учитывая что в нормальных программах не бывает таких "пустых циклов". По крайней мере у меня (под VFP9 SP1) разница при "перестановке границ" между 123 и 1234567 составляет около 10%, а при перестановке объявления переменных в LOCAL - 300% IMHO это заметить гораздо проще нежели 10% Конечно если довести пример до абсурда и сравнивать цикл в 1 итерацию (который вообще-то и не нужен тогда) с циклом в 10E8 итераций то разница будет гораздо существеннее ------------------ WBR, Igor |
Re: Сравнение циклов | |
---|---|
leonid Сообщений: 3204 Откуда: Рига Дата регистрации: 03.02.2006 |
Hi, Igor
Сейчас прямо проверил еще раз. Со сменой локальных переменных у меня (шестой фокс) разница никак не составляет больше 2-3 процентов. При "перестановке границ" между 123 и 1234567 у меня тоже получается что-то около 10, но если 123 уменьшать, то разница начинает расти, и в общем где-то пропорционально тому, как изменяется количество операций. Если число 123 достаточно большое, то почти все затраченное время приходится на первый ENDFOR (он выполняется очень много раз, причем одинаковое в обоих случаях), поэтому разница во времени не очень велика. |
Re: Сравнение циклов | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi leonid!
Естественно что результат зависит от версии фокса - возможно что в 6-ке оно вообще никогда не будет заметно, возможно что повлияет дополнительная переменная (по тупому - в одном из моих тестов добавление "внешнего" однопроходного цикла - т.е. по сути добавление "лишнего" кода - выправило ситуацию и время исполнения перестало зависеть от порядка переменных в LOCAL). Я к тому и говорю - что тема эта слишком тонкая - зависит от особенностей реализации внутренних процедур в разных версиях фокса. ------------------ WBR, Igor |
Re: Сравнение циклов | |
---|---|
leonid Сообщений: 3204 Откуда: Рига Дата регистрации: 03.02.2006 |
Hi Igor!
Конечно, факторов влияющих на скорость очень много, и который из них где сильней проявится, наверное не знают даже разработчики. Кое что можно понять, ставя разные эксперименты, и это полезно, поскольку развивает "интуицию". То, что изменение порядка локальных переменных может измень скорость в разы, знать безусловно полезно. Я как то раньше над этим не задумывался. |
Re: Сравнение циклов | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi leonid!
Цитата:Я тоже Тем более что в реальном применении такая ситуация (пустой цикл) настолько маловероятна... А если цикл не пустой то наверняка и результат будет иной. ------------------ WBR, Igor |
Re: Сравнение циклов | |
---|---|
Foxtrot Автор Сообщений: 3408 Откуда: Куда: Дата регистрации: 25.04.2003 |
мона подвести наверное итоги
а они имхо таковы, что если один из вариантов уже сейчас медленнее при пустых-то проходах, то заполнеие какимнить кодом только усугубит ситуацию всем спасибо зы если всеж переменные смущают, попробуйте заменить циклы на сканы ;) ------------------ Мойте ноги, моя ноги вы моете и руки Исправлено 1 раз(а). Последнее : Foxtrot, 13.07.07 12:05 |
Re: Сравнение циклов | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Hi Канат!
Напротив - заполнение кодом сведёт разницу к минимуму. Например пустые циклы в 12/1234567 итераций при перестановке имеют разницу почти в 2 раза (1.25 против 0.64 секунды), а при заполнении внутреннего цикла всего 2-мя командами lnSum = lnSum + 1 REPLACE n1 WITH m.lnSum Разница составялет всего-то около 5% (23.2 против 22.2 секунды). Вот что существенно - так это содержимое внешнего цикла (помимо самого внутреннего цикла естественно) - ибо число его исполнений прямо зависит от числа итераций внешнего цикла. Но тут уже дело касается логики - нельзя "просто так" менять местами внешний и внутренний циклы. А если внешний всегда пуст - то и смысла в нём нету никакого - т.е. достаточно всего одного цикла с соответствующим числом итераций. ------------------ WBR, Igor |
Re: Сравнение циклов | |
---|---|
h.i.a. Сообщений: 4002 Откуда: Мурманск/Спб/Мск Дата регистрации: 18.11.2005 |
Что-то подкрутили в девятке:
VFP 8 sp1: 11 против 9 сек. VPF 9 sp1: 23 против 9 сек. |
Re: Сравнение циклов | |
---|---|
h.i.a. Сообщений: 4002 Откуда: Мурманск/Спб/Мск Дата регистрации: 18.11.2005 |
А как Вам такой фокус ?
|
Re: Сравнение циклов | |
---|---|
h.i.a. Сообщений: 4002 Откуда: Мурманск/Спб/Мск Дата регистрации: 18.11.2005 |
Ну и напоследок удар ниже пояса...
Исправлено 1 раз(а). Последнее : h.i.a., 13.07.07 17:23 |
Re: Сравнение циклов | |
---|---|
h.i.a. Сообщений: 4002 Откуда: Мурманск/Спб/Мск Дата регистрации: 18.11.2005 |
Вот еще информация к размышлению:
|
Re: Сравнение циклов | |
---|---|
matod Сообщений: 3062 Откуда: Иркутск Дата регистрации: 31.10.2001 |
Занятно... Попробовал эти три теста на одной машине на VFP6 и VFP9.
Для VFP 6.0 SP5 ситуация следующая: 1-й тест: 8.437 8.516 8.437 8.469 2-й тест 8.469 13.656 8.469 13.594 3-й тест: 8.469 8.437 8.422 8.422 Т.е. порядок создания переменных в данном случае значения практически не имеет. Использование глобальных переменных почему-то во второй функции ухудшило результат, т.е. глобальные переменные в 6-ке - все же зло . В VFP9 SP1 картина совсем другая: 1-й тест: 8.688 20.578 20.281 8.656 2-й тест: 8.609 8.547 8.625 8.563 3-й тест 8.516 8.547 8.547 8.562 т.е. в 9-ке в первом тесте получил уже весьма существенные тормоза. А наличие глобальной переменной стабилизирует ситуацию. Причем странные какие-то - я бы понял, если бы результат был 8-20-8-20, т.е. тормозила бы функция с другим порядком переменных. Но получилось именно так 8-20-20-8 Тесты запускал по несколько раз в разной последовательности. Результат неизменен с точностью до 0.1 секунды. Интересно, что в 6-ке добавление в первом тесте в функциях еще 2-х десятков локальных переменных практически не повлияло на результат - те же 8 сек с копейками, что, конечно, противоречит моей гипотезе о потере времени в цикле при поиске переменной. Можно предположить, что при работе цикла for на каждой итерации нет необходимости "искать" переменную - фокс "помнит" ее адрес на время выполнения цикла. |
© 2000-2024 Fox Club  |