in reply to Why is this code so much slower than the same algorithm in C?
Let's look at what is really going on when these programs run.
#include <stdio.h> int main(void) { int i, j; for (i = 20; ; i += 20) { for (j = 1; j < 20; j++) { if (i % j) break; } if (j == 20) { printf("Number: %d\n", i); break; } } return 0; } /* PUBLIC _main EXTRN _printf:NEAR ; Function compile flags: /Ods _TEXT SEGMENT _j$ = -8 _i$ = -4 _main PROC NEAR ; File c:\test\junk.c ; Line 3 push ebp mov ebp, esp push ecx push ecx ; Line 6 mov DWORD PTR _i$[ebp], 20 jmp SHORT $L787 $L788: mov eax, DWORD PTR _i$[ebp] add eax, 20 mov DWORD PTR _i$[ebp], eax $L787: ; Line 7 mov DWORD PTR _j$[ebp], 1 jmp SHORT $L790 $L791: mov eax, DWORD PTR _j$[ebp] inc eax mov DWORD PTR _j$[ebp], eax $L790: cmp DWORD PTR _j$[ebp], 20 jge SHORT $L792 ; Line 8 mov eax, DWORD PTR _i$[ebp] cdq idiv DWORD PTR _j$[ebp] test edx, edx je SHORT $L793 ; Line 9 jmp SHORT $L792 $L793: ; Line 10 jmp SHORT $L791 $L792: ; Line 11 cmp DWORD PTR _j$[ebp], 20 jne SHORT $L794 ; Line 12 push DWORD PTR _i$[ebp] push OFFSET FLAT:$SG795 call _printf pop ecx pop ecx ; Line 13 jmp SHORT $L789 $L794: ; Line 15 jmp SHORT $L788 $L789: ; Line 17 xor eax, eax ; Line 18 leave ret 0 _main ENDP _TEXT ENDS END */
So, whatever terms suits you, which may include one of the following: <opcodes|bytecode|syntax tree|abstract syntax tree|other>.
(Dodge issue!) This is the output from perl -MO=Concise YourScript.pl:
1k <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 junk2.pl:2) v ->3 6 <@> list vKPM/128 ->7 3 <0> pushmark vM/128 ->4 4 <0> padsv[$i:1,8] vM/LVINTRO ->5 5 <0> padsv[$j:1,8] vM/LVINTRO ->6 7 <;> nextstate(main 7 junk2.pl:13) v ->8 a <2> sassign vKS/2 ->b 8 <$> const[IV 20] s ->9 9 <0> padsv[$i:1,8] sRM* ->a - <@> lineseq vK ->1k b <;> nextstate(main 7 junk2.pl:4) v ->c 1j <2> leaveloop vK/2 ->1k c <{> enterloop(next->1f last->1j redo->d) v ->d - <@> lineseq vK ->1j 1e <@> leave vKP ->1f d <0> enter v ->e e <;> nextstate(main 3 junk2.pl:7) v ->f h <2> sassign vKS/2 ->i f <$> const[IV 1] s ->g g <0> padsv[$j:1,8] sRM* ->h - <@> lineseq vK ->10 i <;> nextstate(main 3 junk2.pl:5) v ->j z <2> leaveloop vK/2 ->10 j <{> enterloop(next->s last->z redo->k) v ->v - <1> null vK/1 ->z y <|> and(other->k) vK/1 ->z x <2> lt sK/2 ->y v <0> padsv[$j:1,8] s ->w w <$> const[IV 20] s ->x - <@> lineseq vK ->- r <@> leave vKP ->s k <0> enter v ->l l <;> nextstate(main 2 junk2.pl:6) v + ->m - <1> null vK/1 ->r p <|> and(other->q) vK/1 ->r o <2> modulo[t5] sKP/2 ->p m <0> padsv[$i:1,8] s ->n n <0> padsv[$j:1,8] s ->o q <0> last v* ->r t <1> preinc[t4] vK/1 ->u s <0> padsv[$j:1,8] sRM ->t u <0> unstack v ->v 10 <;> nextstate(main 6 junk2.pl:9) v ->11 - <1> null vKP/1 ->1e 14 <|> and(other->15) vK/1 ->1e 13 <2> eq sK/2 ->14 11 <0> padsv[$j:1,8] s ->12 12 <$> const[IV 20] s ->13 1d <@> leave vKP ->1e 15 <0> enter v ->16 16 <;> nextstate(main 4 junk2.pl:10) v ->17 1a <@> prtf vK ->1b 17 <0> pushmark s ->18 18 <$> const[PV "Number: %d\n"] s ->19 19 <0> padsv[$i:1,8] l ->1a 1b <;> nextstate(main 4 junk2.pl:11) v ->1c 1c <0> last v* ->1d 1h <2> add[t3] vKS/2 ->1i 1f <0> padsv[$i:1,8] sRM ->1g 1g <$> const[IV 20] s ->1h 1i <0> unstack v ->d
And within that, there is one line: o <2> modulo[t5] sKP/2 ->p
which is the equivalent of these four assembly instructions from the C version:
; Line 8 mov eax, DWORD PTR _i$[ebp] cdq idiv DWORD PTR _j$[ebp] test edx, edx
Now let's look at the assembler that sits behind that perl modulo instruction:
PUBLIC _Perl_pp_modulo PUBLIC __real@41f0000000000000 PUBLIC __real@3fe0000000000000 EXTRN _fmod:NEAR EXTRN _floor:NEAR EXTRN _Perl_cast_uv:NEAR ; COMDAT __real@41f0000000000000 CONST SEGMENT __real@41f0000000000000 DQ 041f0000000000000r ; 4.29497e+009 CONST ENDS ; COMDAT __real@3fe0000000000000 CONST SEGMENT __real@3fe0000000000000 DQ 03fe0000000000000r ; 0.5 ; Function compile flags: /Ods CONST ENDS _TEXT SEGMENT tv555 = -128 tv526 = -120 tv272 = -112 tv270 = -108 tv232 = -100 tv206 = -96 tv204 = -92 tv171 = -84 tv75 = -80 _ans$32800 = -76 _dans$32794 = -72 _aiv$32779 = -64 _biv$32756 = -60 _dright$32743 = -56 _right_neg$32740 = -45 _right$32738 = -44 _left$32737 = -40 _dright_valid$32742 = -35 _left_neg$32739 = -34 _use_double$32741 = -33 _dleft$32744 = -32 _right$32719 = -20 _left$32720 = -16 _tmpsv$32718 = -12 _targ$ = -8 _sp$ = -4 _my_perl$ = 8 _Perl_pp_modulo PROC NEAR ; Line 1260 push ebp mov ebp, esp sub esp, 128 ; 00000080H ; Line 1261 mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax] mov DWORD PTR _sp$[ebp], eax mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+4] movzx eax, BYTE PTR [eax+20] and eax, 64 ; 00000040H test eax, eax je SHORT $L37477 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax-4] mov DWORD PTR tv75[ebp], eax jmp SHORT $L37478 $L37477: mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+4] mov eax, DWORD PTR [eax+12] mov ecx, DWORD PTR _my_perl$[ebp] mov ecx, DWORD PTR [ecx+8] mov eax, DWORD PTR [ecx+eax*4] mov DWORD PTR tv75[ebp], eax $L37478: mov eax, DWORD PTR tv75[ebp] mov DWORD PTR _targ$[ebp], eax $L32714: mov eax, DWORD PTR _my_perl$[ebp] cmp DWORD PTR [eax+2624], 0 je $L32715 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov DWORD PTR _right$32719[ebp], eax mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax-4] mov DWORD PTR _left$32720[ebp], eax mov eax, DWORD PTR _left$32720[ebp] mov eax, DWORD PTR [eax+8] and eax, 268435456 ; 10000000H test eax, eax jne SHORT $L32722 mov eax, DWORD PTR _right$32719[ebp] mov eax, DWORD PTR [eax+8] and eax, 268435456 ; 10000000H test eax, eax je $L32715 $L32722: mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+4] movzx eax, BYTE PTR [eax+20] and eax, 64 ; 00000040H neg eax sbb eax, eax and eax, 4 push eax push 14 ; 0000000eH push DWORD PTR _right$32719[ebp] push DWORD PTR _left$32720[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_amagic_call add esp, 20 ; 00000014H mov DWORD PTR _tmpsv$32718[ebp], eax cmp DWORD PTR _tmpsv$32718[ebp], 0 je $L32715 mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax] mov DWORD PTR _sp$[ebp], eax mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax $L32724: mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+4] movzx eax, BYTE PTR [eax+20] and eax, 64 ; 00000040H test eax, eax jne SHORT $L32728 mov eax, DWORD PTR _targ$[ebp] mov eax, DWORD PTR [eax+8] and eax, 1024 ; 00000400H test eax, eax je SHORT $L32727 $L32728: push 2 push DWORD PTR _tmpsv$32718[ebp] push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_sv_setsv_flags add esp, 16 ; 00000010H $L32732: mov eax, DWORD PTR _targ$[ebp] mov eax, DWORD PTR [eax+8] and eax, 16384 ; 00004000H test eax, eax je SHORT $L32733 push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_mg_set pop ecx pop ecx $L32733: xor eax, eax test eax, eax jne SHORT $L32732 mov eax, DWORD PTR _sp$[ebp] mov ecx, DWORD PTR _targ$[ebp] mov DWORD PTR [eax], ecx xor eax, eax test eax, eax jne SHORT $L32732 jmp SHORT $L32725 $L32727: mov eax, DWORD PTR _sp$[ebp] mov ecx, DWORD PTR _tmpsv$32718[ebp] mov DWORD PTR [eax], ecx $L32725: xor eax, eax test eax, eax jne SHORT $L32724 mov eax, DWORD PTR _my_perl$[ebp] mov ecx, DWORD PTR _sp$[ebp] mov DWORD PTR [eax], ecx mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+4] mov eax, DWORD PTR [eax] jmp $L32711 $L32715: xor eax, eax test eax, eax jne $L32714 ; Line 1263 and DWORD PTR _left$32737[ebp], 0 ; Line 1264 and DWORD PTR _right$32738[ebp], 0 ; Line 1265 and BYTE PTR _left_neg$32739[ebp], 0 ; Line 1266 and BYTE PTR _right_neg$32740[ebp], 0 ; Line 1267 and BYTE PTR _use_double$32741[ebp], 0 ; Line 1268 and BYTE PTR _dright_valid$32742[ebp], 0 ; Line 1269 fldz fstp QWORD PTR _dright$32743[ebp] ; Line 1270 fldz fstp QWORD PTR _dleft$32744[ebp] $L32745: ; Line 1272 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 16777216 ; 01000000H test eax, eax jne SHORT $L32746 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 131072 ; 00020000H test eax, eax jne SHORT $L32749 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 262144 ; 00040000H test eax, eax je SHORT $L32746 $L32749: mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 65536 ; 00010000H test eax, eax je SHORT $L37479 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+12] mov DWORD PTR tv171[ebp], eax jmp SHORT $L32746 $L37479: mov eax, DWORD PTR _sp$[ebp] push DWORD PTR [eax] push DWORD PTR _my_perl$[ebp] call _Perl_sv_2iv pop ecx pop ecx mov DWORD PTR tv171[ebp], eax $L32746: xor eax, eax test eax, eax jne SHORT $L32745 ; Line 1273 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 65536 ; 00010000H test eax, eax je SHORT $L32752 ; Line 1274 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, -2147418112 ; 80010000H xor ecx, ecx cmp eax, -2147418112 ; 80010000H setne cl mov BYTE PTR _right_neg$32740[ebp], cl ; Line 1275 movsx eax, BYTE PTR _right_neg$32740[ebp] test eax, eax jne SHORT $L32753 ; Line 1276 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+12] mov DWORD PTR _right$32738[ebp], eax mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax ; Line 1277 jmp SHORT $L32755 $L32753: ; Line 1278 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+12] mov DWORD PTR _biv$32756[ebp], eax mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax ; Line 1279 cmp DWORD PTR _biv$32756[ebp], 0 jl SHORT $L32758 ; Line 1280 mov eax, DWORD PTR _biv$32756[ebp] mov DWORD PTR _right$32738[ebp], eax ; Line 1281 and BYTE PTR _right_neg$32740[ebp], 0 ; Line 1282 jmp SHORT $L32755 $L32758: ; Line 1283 mov eax, DWORD PTR _biv$32756[ebp] neg eax mov DWORD PTR _right$32738[ebp], eax $L32755: ; Line 1287 jmp $L32767 $L32752: ; Line 1288 mov eax, DWORD PTR _my_perl$[ebp] mov ecx, DWORD PTR _sp$[ebp] mov ecx, DWORD PTR [ecx] mov DWORD PTR [eax+84], ecx mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+84] mov eax, DWORD PTR [eax+8] and eax, 131072 ; 00020000H test eax, eax je SHORT $L37481 mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+84] mov eax, DWORD PTR [eax] fld QWORD PTR [eax+16] fstp QWORD PTR tv204[ebp] jmp SHORT $L37482 $L37481: mov eax, DWORD PTR _my_perl$[ebp] push DWORD PTR [eax+84] push DWORD PTR _my_perl$[ebp] call _Perl_sv_2nv pop ecx pop ecx fstp QWORD PTR tv204[ebp] $L37482: fld QWORD PTR tv204[ebp] fst QWORD PTR _dright$32743[ebp] ; Line 1289 fcomp QWORD PTR __real@0000000000000000 fnstsw ax test ah, 5 jp SHORT $L37483 mov DWORD PTR tv206[ebp], 1 jmp SHORT $L37484 $L37483: and DWORD PTR tv206[ebp], 0 $L37484: mov al, BYTE PTR tv206[ebp] mov BYTE PTR _right_neg$32740[ebp], al ; Line 1290 movsx eax, BYTE PTR _right_neg$32740[ebp] test eax, eax je SHORT $L32762 ; Line 1291 fld QWORD PTR _dright$32743[ebp] fchs fstp QWORD PTR _dright$32743[ebp] $L32762: ; Line 1292 fld QWORD PTR _dright$32743[ebp] fcomp QWORD PTR __real@41f0000000000000 fnstsw ax test ah, 5 jp SHORT $L32764 ; Line 1293 fld QWORD PTR _dright$32743[ebp] push ecx push ecx fstp QWORD PTR [esp] push DWORD PTR _my_perl$[ebp] call _Perl_cast_uv add esp, 12 ; 0000000cH mov DWORD PTR _right$32738[ebp], eax ; Line 1294 mov BYTE PTR _dright_valid$32742[ebp], 1 ; Line 1295 jmp SHORT $L32767 $L32764: ; Line 1296 mov BYTE PTR _use_double$32741[ebp], 1 $L32767: ; Line 1303 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 16777216 ; 01000000H test eax, eax jne SHORT $L32768 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 131072 ; 00020000H test eax, eax jne SHORT $L32771 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 262144 ; 00040000H test eax, eax je SHORT $L32768 $L32771: mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 65536 ; 00010000H test eax, eax je SHORT $L37485 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+12] mov DWORD PTR tv232[ebp], eax jmp SHORT $L32768 $L37485: mov eax, DWORD PTR _sp$[ebp] push DWORD PTR [eax] push DWORD PTR _my_perl$[ebp] call _Perl_sv_2iv pop ecx pop ecx mov DWORD PTR tv232[ebp], eax $L32768: xor eax, eax test eax, eax jne SHORT $L32767 ; Line 1304 movsx eax, BYTE PTR _use_double$32741[ebp] test eax, eax jne $L32774 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 65536 ; 00010000H test eax, eax je $L32774 ; Line 1305 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, 65536 ; 00010000H test eax, eax je SHORT $L32775 ; Line 1306 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+8] and eax, -2147418112 ; 80010000H xor ecx, ecx cmp eax, -2147418112 ; 80010000H setne cl mov BYTE PTR _left_neg$32739[ebp], cl ; Line 1307 movsx eax, BYTE PTR _left_neg$32739[ebp] test eax, eax jne SHORT $L32776 ; Line 1308 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+12] mov DWORD PTR _left$32737[ebp], eax mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax ; Line 1309 jmp SHORT $L32775 $L32776: ; Line 1310 mov eax, DWORD PTR _sp$[ebp] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax] mov eax, DWORD PTR [eax+12] mov DWORD PTR _aiv$32779[ebp], eax mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax ; Line 1311 cmp DWORD PTR _aiv$32779[ebp], 0 jl SHORT $L32781 ; Line 1312 mov eax, DWORD PTR _aiv$32779[ebp] mov DWORD PTR _left$32737[ebp], eax ; Line 1313 and BYTE PTR _left_neg$32739[ebp], 0 ; Line 1314 jmp SHORT $L32775 $L32781: ; Line 1315 mov eax, DWORD PTR _aiv$32779[ebp] neg eax mov DWORD PTR _left$32737[ebp], eax $L32775: ; Line 1320 jmp $L32783 $L32774: ; Line 1321 mov eax, DWORD PTR _my_perl$[ebp] mov ecx, DWORD PTR _sp$[ebp] mov ecx, DWORD PTR [ecx] mov DWORD PTR [eax+84], ecx mov eax, DWORD PTR _sp$[ebp] sub eax, 4 mov DWORD PTR _sp$[ebp], eax mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+84] mov eax, DWORD PTR [eax+8] and eax, 131072 ; 00020000H test eax, eax je SHORT $L37487 mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+84] mov eax, DWORD PTR [eax] fld QWORD PTR [eax+16] fstp QWORD PTR tv270[ebp] jmp SHORT $L37488 $L37487: mov eax, DWORD PTR _my_perl$[ebp] push DWORD PTR [eax+84] push DWORD PTR _my_perl$[ebp] call _Perl_sv_2nv pop ecx pop ecx fstp QWORD PTR tv270[ebp] $L37488: fld QWORD PTR tv270[ebp] fst QWORD PTR _dleft$32744[ebp] ; Line 1322 fcomp QWORD PTR __real@0000000000000000 fnstsw ax test ah, 5 jp SHORT $L37489 mov DWORD PTR tv272[ebp], 1 jmp SHORT $L37490 $L37489: and DWORD PTR tv272[ebp], 0 $L37490: mov al, BYTE PTR tv272[ebp] mov BYTE PTR _left_neg$32739[ebp], al ; Line 1323 movsx eax, BYTE PTR _left_neg$32739[ebp] test eax, eax je SHORT $L32785 ; Line 1324 fld QWORD PTR _dleft$32744[ebp] fchs fstp QWORD PTR _dleft$32744[ebp] $L32785: ; Line 1328 movsx eax, BYTE PTR _use_double$32741[ebp] test eax, eax jne SHORT $L32783 ; Line 1329 fld QWORD PTR _dleft$32744[ebp] fcomp QWORD PTR __real@41f0000000000000 fnstsw ax test ah, 5 jp SHORT $L32788 ; Line 1332 fld QWORD PTR _dleft$32744[ebp] push ecx push ecx fstp QWORD PTR [esp] push DWORD PTR _my_perl$[ebp] call _Perl_cast_uv add esp, 12 ; 0000000cH mov DWORD PTR _left$32737[ebp], eax ; Line 1336 jmp SHORT $L32783 $L32788: ; Line 1340 fld QWORD PTR _dleft$32744[ebp] fadd QWORD PTR __real@3fe0000000000000 push ecx push ecx fstp QWORD PTR [esp] call _floor pop ecx pop ecx fstp QWORD PTR _dleft$32744[ebp] ; Line 1341 mov BYTE PTR _use_double$32741[ebp], 1 ; Line 1342 movsx eax, BYTE PTR _dright_valid$32742[ebp] test eax, eax je SHORT $L32791 ; Line 1343 fld QWORD PTR _dright$32743[ebp] fadd QWORD PTR __real@3fe0000000000000 push ecx push ecx fstp QWORD PTR [esp] call _floor pop ecx pop ecx fstp QWORD PTR _dright$32743[ebp] ; Line 1344 jmp SHORT $L32783 $L32791: ; Line 1345 mov eax, DWORD PTR _right$32738[ebp] mov DWORD PTR tv526[ebp], eax and DWORD PTR tv526[ebp+4], 0 fild QWORD PTR tv526[ebp] fstp QWORD PTR _dright$32743[ebp] $L32783: ; Line 1349 movsx eax, BYTE PTR _use_double$32741[ebp] test eax, eax je $L32793 ; Line 1352 fld QWORD PTR _dright$32743[ebp] fcomp QWORD PTR __real@0000000000000000 fnstsw ax test ah, 68 ; 00000044H jp SHORT $L32795 ; Line 1353 push OFFSET FLAT:$SG32796 push DWORD PTR _my_perl$[ebp] call _Perl_die pop ecx pop ecx jmp $L32711 $L32795: ; Line 1355 fld QWORD PTR _dright$32743[ebp] push ecx push ecx fstp QWORD PTR [esp] fld QWORD PTR _dleft$32744[ebp] push ecx push ecx fstp QWORD PTR [esp] call _fmod add esp, 16 ; 00000010H fstp QWORD PTR _dans$32794[ebp] ; Line 1356 movsx eax, BYTE PTR _left_neg$32739[ebp] movsx ecx, BYTE PTR _right_neg$32740[ebp] cmp eax, ecx je SHORT $L32797 fld QWORD PTR _dans$32794[ebp] fcomp QWORD PTR __real@0000000000000000 fnstsw ax test ah, 68 ; 00000044H jnp SHORT $L32797 ; Line 1357 fld QWORD PTR _dright$32743[ebp] fsub QWORD PTR _dans$32794[ebp] fstp QWORD PTR _dans$32794[ebp] $L32797: ; Line 1358 movsx eax, BYTE PTR _right_neg$32740[ebp] test eax, eax je SHORT $L32798 ; Line 1359 fld QWORD PTR _dans$32794[ebp] fchs fstp QWORD PTR _dans$32794[ebp] $L32798: ; Line 1360 fld QWORD PTR _dans$32794[ebp] push ecx push ecx fstp QWORD PTR [esp] push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_sv_setnv add esp, 16 ; 00000010H ; Line 1362 jmp $L32814 $L32793: ; Line 1365 cmp DWORD PTR _right$32738[ebp], 0 jne SHORT $L32801 ; Line 1366 push OFFSET FLAT:$SG32802 push DWORD PTR _my_perl$[ebp] call _Perl_die pop ecx pop ecx jmp $L32711 $L32801: ; Line 1368 mov eax, DWORD PTR _left$32737[ebp] xor edx, edx div DWORD PTR _right$32738[ebp] mov DWORD PTR _ans$32800[ebp], edx ; Line 1369 movsx eax, BYTE PTR _left_neg$32739[ebp] movsx ecx, BYTE PTR _right_neg$32740[ebp] cmp eax, ecx je SHORT $L32803 cmp DWORD PTR _ans$32800[ebp], 0 je SHORT $L32803 ; Line 1370 mov eax, DWORD PTR _right$32738[ebp] sub eax, DWORD PTR _ans$32800[ebp] mov DWORD PTR _ans$32800[ebp], eax $L32803: ; Line 1371 movsx eax, BYTE PTR _right_neg$32740[ebp] test eax, eax je SHORT $L32804 ; Line 1374 cmp DWORD PTR _ans$32800[ebp], -2147483647 ; 80000001H ja SHORT $L32807 ; Line 1375 mov eax, DWORD PTR _ans$32800[ebp] not eax inc eax push eax push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_sv_setiv add esp, 12 ; 0000000cH ; Line 1376 jmp SHORT $L32808 $L32807: ; Line 1377 mov eax, DWORD PTR _ans$32800[ebp] mov DWORD PTR tv555[ebp], eax and DWORD PTR tv555[ebp+4], 0 fild QWORD PTR tv555[ebp] fchs push ecx push ecx fstp QWORD PTR [esp] push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_sv_setnv add esp, 16 ; 00000010H $L32808: ; Line 1379 jmp SHORT $L32814 $L32804: ; Line 1380 push DWORD PTR _ans$32800[ebp] push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_sv_setuv add esp, 12 ; 0000000cH $L32814: ; Line 1382 mov eax, DWORD PTR _targ$[ebp] mov eax, DWORD PTR [eax+8] and eax, 16384 ; 00004000H test eax, eax je SHORT $L32815 push DWORD PTR _targ$[ebp] push DWORD PTR _my_perl$[ebp] call _Perl_mg_set pop ecx pop ecx $L32815: xor eax, eax test eax, eax jne SHORT $L32814 mov eax, DWORD PTR _sp$[ebp] add eax, 4 mov DWORD PTR _sp$[ebp], eax mov eax, DWORD PTR _sp$[ebp] mov ecx, DWORD PTR _targ$[ebp] mov DWORD PTR [eax], ecx xor eax, eax test eax, eax jne SHORT $L32814 ; Line 1383 mov eax, DWORD PTR _my_perl$[ebp] mov ecx, DWORD PTR _sp$[ebp] mov DWORD PTR [eax], ecx mov eax, DWORD PTR _my_perl$[ebp] mov eax, DWORD PTR [eax+4] mov eax, DWORD PTR [eax] $L32711: ; Line 1385 leave ret 0 _Perl_pp_modulo ENDP _TEXT ENDS
So the answer to your question is: when you understand why those four instructions in the C version, require those 700+ lines of assembler for the perl version, then you'll understand why the performance difference exists.
And also why it isn't a problem!
|
|---|