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.

  1. First the C program. It translates into the following assembler:
    #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 */
  2. Now the Perl code. It translates into the following ... um...I terrified to apply a term to this because one or more of the local language laywers is going to leap all over what ever term I use to say that it isn't really 'term' because blah, blah, ... more irrelavancies, ... blah!

    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:

    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:

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!


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."