Originally posted by impersonalis@Sep 19 2005, 04:39 PM
Настоятельно рекомендую использовать операцию *.5 вместо /2, и вот почему.
Простенький тест уменьшит все числа ряда от 1 до 30000 двумя способами, измерив при этом время выполнения:
time1=MilliSecs()
For i=1 To 30000
a=i/2
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 30000
a=i*.5
Next
time2=MilliSecs()-time2
Print " [\2] "+time1
Print " [*.5] "+time2
WaitKey()
У меня результаты 75 и 4* :o
Комментарии излишни...
|
Возвращаясь к вышеизложенному, с прискорбием сообщаю, что ув. г-н Impersonalis не прав абсолютно. Меня заинтересовала полученная разница во времени, которая не может быть объяснена никакими таймингами и тактами процессора, FPU и т.д.
Итак, ищем причину странного явления.
Добавим в самое начало программы простую строку - Delay 3000.
Происходит чудо
) - времена выравниваются! Если задержку уменьшать, то, соответственно, первое время начинает возрастать. Что происходит? Смотрим - режим отладки включен! Вот он, мерзавец, и вступил в тайный сговор с Impersonalisom!
Но нет, если поменять местами а=i/2 и a=i*.5, то есть a=i*.5 вставить в первый цикл, то НИЧЕГО не меняется!
Просто - напросто при включенной отладке запускается дополнительно в фоне основной программы инициализация отладчика - выделяется память под символьные переменные, переключается стек, нумеруются строки и пр. Это может длится пару секунд (чем слабее процессор, тем дольше). Соответственно, самый первый тест выполняется медленнее.
Чтобы это устранить, нужно задать в цикле не 30 тысяч вычислений, а три миллиона. Тогда этот эффект нивелируется. Ну а лучше вообще отключить отладку и попробовать посчитать:
time1=MilliSecs()
For i=1 To 3000000
* *a = i * .5
Next
time1=MilliSecs()-time1
time2=MilliSecs()
For i=1 To 3000000
* *a = i / 2
Next
time2=MilliSecs()-time2
time3=MilliSecs()
For i=1 To 3000000
* *a = i Shr 2
Next
time3=MilliSecs()-time3
time4=MilliSecs()
For i=1 To 3000000
* *b# = i / 3
Next
time4=MilliSecs()-time4
Print " [*.5] " * + time1
Print " [/2] " * *+ time2
Print " [shr 2] " + time3
Print " [/3#] " * + time4
WaitKey()
Теперь все встает на свои места. У множение на .5 использует FPU, естественно, оно медленнее регистрового сдвига SHR 1. Деление на 2 целого числа компилятор заменяет на сдвиг, поэтому деление целых чисел на 2 ГОРАЗДО БЫСТРЕЕ умножения на .5. Ну и медленне всего (из представленных вариантов) выполняется деление на 3.
ЛОГИЧЕСКИЙ СДВИГ РУЛИТ - это делается одним сдвигом процессорного регистра!
Предлагаю тов. Impersonalis заменить рекламный слоган.