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.
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!
|
|---|