Burster_TIL писал(а):Не совсем так. Я говорил про то, что я компилирую две ф-ции в одном проекте. Она ниже. И у неё ощутимо большее число тиков выходит. Твоя и эта компилируется при одинаковых условиях. Ибо это всё в одном проекте.
Давай для начала договоримся о таких вещах, чтобы все кто читает этот форум понимали лучше.
1) Когда ты говоришь в "одном проекте" то ты сразу прилагай 
весь текст программы, желательно аттачем (положенным в .zip). Отлаживать куски кода очень и очень неблагодарное дело. 
2) нету "твоей" и "этой" функции. Т.к. яваскрипт ещё не полностью захавал мозг делфи программистам, мы всё ещё присваиваем имена процедурам и функциями. И по-этому используй выражения вроде. "Я говорил про то, что я компилирую две ф-ции в одном проекте. Она -Test_Speed - ниже. И у неё ощутимо большее число тиков выходит. Твоя (BigTest) и эта (Test_Speed) компилируется при одинаковых условиях"
3) пожалуйста используй 
тэг code (статья на английском но с картинками понятно!)
Это важно, т.к. если ты и я может кое-как и понимаем где чья функия, другие участники не поймут.
Ну а теперь о разнице! Как я говорил выше, если ты скомпилируешь програмку с ключиком "-al" то у тебя появится  ассебмлерный код.
Но лучше сделать даже так:
- Код: Выделить всё
- fpc -al -O3 -Amasm test.pas
 
Разница будет в синтаксисе ассебмлера. Если использовать -Amasm то ассебмлер будет в 
Интеловском-синтаксе, который может увидеть и в Delphi. Очень удобно для сравнения скажем Delphi и FPC кода. 
Так вот, смотрим в ассемблеры. Цикл для Test_Speed выглядит следующий образом
- Код: Выделить всё
- ; [35] for j:=0 to 19 do
 mov   dword ptr [ebp-20],0
 dec   dword ptr [ebp-20]
 ALIGN 4
 @@j34:
 inc   dword ptr [ebp-20]
 ; [37] i:=1000;
 mov   dword ptr [ebp-4],1000
 ; [38] T1:=Get__RDTSC;
 call   P$PROGRAM_GET__RDTSC$$INT64
 mov   dword ptr [ebp-16],eax
 mov   dword ptr [ebp-12],edx
 ; [39] for i:=0 to 1000 do
 mov   dword ptr [ebp-4],0
 dec   dword ptr [ebp-4]
 ALIGN 4
 @@j41:
 inc   dword ptr [ebp-4]
 ; [41] a:=0;
 mov   ebx,0
 cmp   dword ptr [ebp-4],1000
 jl   @@j41
 ; [43] T2:=Get__RDTSC;
 call   P$PROGRAM_GET__RDTSC$$INT64
 mov   dword ptr [ebp-8],eax
 mov   esi,edx
 
а цикл для BigTest выглядит так:
- Код: Выделить всё
- ; [21] T1:=Get__RDTSC;
 call   P$PROGRAM_GET__RDTSC$$INT64
 mov   ebx,eax
 mov   esi,edx
 ; [22] i:=1000;
 mov   eax,1000
 ; [23] for i:=0 to 1000 do
 mov   edx,0
 dec   edx
 ALIGN 4
 @@j23:
 inc   edx
 ; [25] a:=0;
 mov   eax,0
 cmp   edx,1000
 jl   @@j23
 ; [26] T2:=Get__RDTSC;
 call   P$PROGRAM_GET__RDTSC$$INT64
 
Так вот, обрати внимание что в коде Test_Speed можно часто увидеть выражение вроде:
- Код: Выделить всё
- dword ptr [ebp-NNN]
 
а в коде BigTest их нет вообще. И это причина тормозов - dword ptr [ebp-NNN] - заставляет процессор оперировать с памятью. 
Тогда как BigTest оперирует не с памятью а исключительно с регистрами процессора.
Почему FPC так сделал. Обычно счётчики цикла лежат в регистре, а не памяти процессора, но т.к. у тебя есть вложенный цикл, то регистров (коих мало) на всё не хватит, и FPC генерирует код, который оперирует с памятью. Что вызывает "тормоза" но зато код работает.
В реальной жизни, когда цикл будет делать нечто большее, чем просто присваивать 0 в переменную a, оперирования с памятью не избежать вообще, и скорость сравняется и между циклами и между компиляторами (delphi и fpc).