Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is repeat(x).take(n) performant?

I'm looking for an efficient way to write the following function, as discussed in another question:

fn dots(n: usize) -> String {
    std::iter::repeat('.').take(n).collect()
}

Does Rust generate concrete types for instances of generic struct types? Is the result of repeat('.').take(n) (the struct Take<Repeat<char>>) equivalent to

struct Take_Repeat_char {
    element: char,
    n: usize
}

Are method implementations inlined - will there be a version of Take::next() that has Repeat::next() inlined in it?

What is a good way to check this for myself? Inspecting LLVM IR?

like image 679
Michał Bendowski Avatar asked Oct 03 '15 11:10

Michał Bendowski


1 Answers

Yes, this is Rusty™ enough. And yes, LLVM will inline the whole thing if you compile with optimizations (e.g. cargo build --release). Check via play.rust-lang.org and look at the generated assembly. The code in question is:

movb    $46, (%rax)
movb    $46, 1(%rax)
movb    $46, 2(%rax)
movb    $46, 3(%rax)
movb    $46, 4(%rax)

for five dots. I believe it might be possible to go faster by merging the first four dots into one

movd    $x2e2e2e2e, (%rax)

instruction, but I don't think it will make much of a difference. Edit: Actually depending on memory alignment, it may be faster or slower: if %rax is aligned, it could probably be a bit faster (depending on complex things like caches, prefetching, etc.), otherwise it will probably be slower (because of possible traps).

like image 152
llogiq Avatar answered Sep 21 '22 19:09

llogiq