Jan 26, 2016

Whoa, that was fast! [Rust]

Browsing through Rust tutorial book's chapter Rust Inside Other Languages I was wandering, why the sample is running kind of slow (in non-release compilation): running a ten times slower than equivalent Delphi source.

Lets take a look at disassembled code for this fragment:

      for _ in 0..5_000_000 {

If you know that Rust's for is actually a syntax sugar for iterators, the result should no be so surprising:


        mov     dword ptr [rbp - 128], 0 // starting value
        mov     dword ptr [rbp - 124], 5000000 // ending value
        mov     rdi, qword ptr [rbp - 128]
        call    IntoIterator_into_iter
        ....
        mov     qword ptr [rbp - 264], rdi // iterator

Later Iterator::next() method will be called in a loop, returning Some(_) (actual value is ignored) or None, when iterator is done:


        mov     rdi, qword ptr [rbp - 264] // iterator
        call    Iterator_next
        mov     qword ptr [rbp - 152], rax // Option
        mov     qword ptr [rbp - 160], rax // 
        mov     ecx, dword ptr [rbp - 160]
        sub     ecx, 1
        ...
        je      loop_body
        jmp     break


The call to Iterator::next() is costly, it is far from as simple as "inc eax", that is why sample is running so slow.

One interesting note is what happening when you compile with --release switch. Lets take a look at our iterator loop:


        mov     rax, 004C4B400000001h    // hex 4C4B40 is 5000000 in decimal
        mov     [rsi], rax

Well, apparently compiler has outsmarted the programmer.


Whoa, that was fast!