top := number shr 1;
for i := 2 to top do
begin
{bla-bla}
end;
Какой из двух кусков кода оптимальней?
Какой из двух кусков кода оптимальней?
Код:
Код:
for i := 2 to (number shr 1) do
begin
{bla-bla}
end;
begin
{bla-bla}
end;
Если number в цикле меняется то конечно первый вариант быстрее но он становится совсем бесполезным. (Правда если компилятор совсем тупой то он может соптимизировать второй вариант чтоб было как в первом и тут у тебя уже проблемы :) и чтото мне припоминается-мерещется что на паскале так и будет правда я не уверен)
Предлагаю поекспериментировать изменяя number в цыкле и посмотреть самому.
Если ошибку испроавить, то одинаково.
И всё таки. В первом варианте один раз выполняется сдвиг (то бишь целочисленное деление на два), заносится в переменную в памяти и потом много-много раз значение из этой памяти считывается. Во втором же случае просто много-много раз выполняется сдвиг. И вот на уровне машинных кодов что быстрее - считывание из памяти или сдвиг?
Чтение из основного объема оперативной памяти в десятки, а то и сотню раз медленнее, чем сдвиг. Из кэш-памяти - быстрее, чем из основной, но все равно медленнее, чем внутрипроцессорные операции.
Цитата: andriano
Во втором случае сдвиг тоже выполняется один раз.
А от компилятора это зависит? Или так в спецификации написано?
Но можно проверить например, написав функцию которая это делает сдвиг и возвращает результат. а также, изменяет некую глобальную переменну счетчик, и посмотреть сколько раз она зайдет туда.
То, что после to, вычисляется один раз, перед выполнением цикла. И это бывает иногда хорошо, иногда плохо. Но чаще хорошо, так как сто раз одно и то же не вычисляется, а если переменная изменяется в цикле - для этого есть while и repeat.
Если изменяется - программа составлена неверно и результат работы такой программы неопределен.
Исходя из этого, все параметры, задающие цикл, вычисляются до его начала и в дальнейшем не перевычисляются.
И, кстати, это ВСЕГДА хорошо. Т.к. гарантирует оптимальную работу любой правильно составленной программы.
Цитата: andriano
Исходя из этого, все параметры, задающие цикл, вычисляются до его начала и в дальнейшем не перевычисляются.
И, кстати, это ВСЕГДА хорошо.
И, кстати, это ВСЕГДА хорошо.
Согласен, но если вспомнить еще TP под DOS, там можно было в цикле изменить сам счетчик. То есть код:
[highlight=Pascal]
for i := 0 to n - 1 do
i := 15;
[/highlight]
был вполне допустим. В Delphi эту особенность исключили.
В частности: такая программа может
- выдавать один результат,
- выдавать другой результат,
- не компилироваться,
- подвешивать компьютер.
То, что компиляторы ведут себя по-разному на неправильном коде, вполне естественно. Компилятор не может обнаружить ВСЕ ошибки.
Цитата: Somebody
То, что после to, вычисляется один раз, перед выполнением цикла.
А где он это значение хранить будет? В основной памяти? Если там стоит выражение, то под результат память выделяется отдельно? А если одна переменная?
Это уже дело компилятора (а также системы команд используемого процессора). Может хранить в стеке, может - в регистре.