![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вынесение инвариантного кода за пределы цикла [D6]
MU © (2005-03-06 13:08:00)В статье на этом сайте http://www.delphimaster.ru/articles/optimization.html
прочитал следущее:
Вынесение инвариантного кода за пределы цикла – не выносится. Наиболее распространенный недочет – условие цикла записывается как:
for i:=0 to memo1.lines.count – 1 do...
Delphi будет при каждой итерации вызывать метод count, вычитать из результата 1 и потом уже сверять. Настоятельно рекомендуется переписывать подобный код как
lin := .lines.count – 1;
for i:=0 to lin do...
Весь код VCL написан с нарушением этого правила. Очевидно, что проще подобного рода оптимизацию встроить в компилятор, нежели переписывать VCL :)
Честно говоря, удивился.
Так ли это?
GuAV (2005-03-06 23:39:00) [1]
> на самом деле, неисповедимы пути оптимизации
воистину. однако тогда нефиг пытаться исповедовать их. а [0] - эт уже не оптимизация а язык.
SergP (2005-03-06 23:02:00) [2]
> [3] Anatoly Podgoretsky © (06.03.05 13:55)
> Да муру автор написал, ...
А разве премодерации нет?
Palladin (2005-03-06 22:36:00) [3]нет, в оршник нельзя, на самом деле, неисповедимы пути оптимизации
MU (2005-03-06 22:33:00) [4]Юрий Зотов © (06.03.05 22:25) [7]
>> проводилось... при отключенной оптимизации.
:))
Может, в Орешник ее, статью-то
Юрий Зотов (2005-03-06 22:25:00) [5]Еще один перл оттуда же (тоже по поводу цикла for):
"Замена инкремента на декремент – не производится. Более того, даже декрементный цикл компилируется в неоптимальный код, т.к. не используется флаг ZF. Вместо этого происходит сравнивание значения регистра с 0".
Судя по тексту статьи, автор неоднократно заглядывал в окно CPU, поэтому не увидеть замену инкремента на декремент он никак не мог. Тем не менее, не увидел. Почему?
Напрашивается такой ответ - исследование оптимизирующих свойств компилятора Delphi проводилось... при отключенной оптимизации.
GuAV (2005-03-06 22:13:00) [6]Дмитрий Мыльников (06.03.05 21:55) [5]
начиная с D4 (если правильно помню)
Видимо неправильно ибо пример в [1] работает и в Borland Pascal 7.0
> хотя, во времена паскаля цикл for работал медленее
> while, и я в основном старался использовать его, а
> сейчас, из-за использования регистровой переменной для
> счётчика, стало наоборот.
for тоже может считать стековой (а while - регистровой). Тем не менее for обычно лучше оптимизируется.
Дмитрий Мыльников (2005-03-06 21:55:00) [7]начиная с D4 (если правильно помню) она умеет оптимизировать циклы fоr так, чтобы значения границ вычислялись только один раз. В качестве примера можете попробовать выполнить тест
for I := 0 to List.Count - 1 do
List.Delete(I);
если количество элементов больше нуля, то он упадёт.
Кстати, с этого же момента в качестве счётчика цикла можно использовать только локальные переменные, которые при этом компилятор помещает во время цикла в регистр, а не на стек. Если же попытаться использовать статическую переменную, то компилятор выдаст ошибку.
Хотя, я до сих пор по привычке ещё со времён паскаля пишу
var i, ei: integer;
...
ei := List.Count - 1;
for i := 0 to ei do
...
хотя, во времена паскаля цикл for работал медленее while, и я в основном старался использовать его, а сейчас, из-за использования регистровой переменной для счётчика, стало наоборот.
Petr V. Abramov (2005-03-06 16:03:00) [8]особенно умиляет "подставляйте в код непосредственные значения" :)
Anatoly Podgoretsky (2005-03-06 13:55:00) [9]Да муру автор написал, не удосужился даже посмотреть справку по FOR, которая гласит, для I от Start до End, выполнить N раз
MU (2005-03-06 13:13:00) [10]Я тоже так всегда думал...
Зачем тогда помещать такую "статью"?
Или это уже в "Потрепаться"?
GuAV (2005-03-06 13:11:00) [11]нет.
выражения заданные как границы в цикле for считаются только один раз.
пример
I := 0;
for I := 1 to I + 5 do
WriteLn(I);
только 5 итераций.