我正在寻找一种有效的方法来编写以下函数,如另一个问题所述:
fn dots(n: usize) -> String {
std::iter::repeat('.').take(n).collect()
}
Run Code Online (Sandbox Code Playgroud)
Rust是否为泛型结构类型的实例生成具体类型?是repeat('.').take(n)(结构Take<Repeat<char>>)的结果等同于
struct Take_Repeat_char {
element: char,
n: usize
}
Run Code Online (Sandbox Code Playgroud)
是方法实现内联-会不会有一个版本Take::next()已经Repeat::next()在它内联?
有什么好办法自己检查一下?检查LLVM IR?
llo*_*giq 12
是的,这足够Rusty™.是的,如果您使用优化进行编译(例如cargo build --release),LLVM将内联整个事情.通过play.rust-lang.org查看并查看生成的程序集.有问题的代码是:
movb $46, (%rax)
movb $46, 1(%rax)
movb $46, 2(%rax)
movb $46, 3(%rax)
movb $46, 4(%rax)
Run Code Online (Sandbox Code Playgroud)
五点.我相信通过将前四个点合并为一个可能会更快
movd $x2e2e2e2e, (%rax)
Run Code Online (Sandbox Code Playgroud)
指导,但我认为它不会产生太大的影响.编辑:实际上取决于内存对齐,它可能更快或更慢:如果%rax对齐,它可能会更快(取决于复杂的事情,如缓存,预取等),否则它可能会更慢(因为可能陷阱).
Rust是否为泛型结构类型的实例生成具体类型?
是的,这称为单形化.
方法实现内联吗?
像许多语言一样,这是一个坚实的"可能".有一些提示可以提供编译器来控制内部和内部包的内联,但通常由编译器来做正确的事情.如上所述,如果函数使用泛型类型,它将自动用于单态化,这意味着内联它所需的信息在编译的包中可用.
有什么好办法自己检查一下?
许多人将使用Rust Playground来查看LLVM IR或程序集.当然,您可以在本地查看rustc --emit [asm|llvm-ir].在这样做的时候,我把我感兴趣的代码放在一个永远不会内联的函数中.这使得在装配/ IR输出中更容易找到:
#[inline(never)]
fn dots(n: usize) -> String {
std::iter::repeat('.').take(n).collect()
}
Run Code Online (Sandbox Code Playgroud)
正如llogiq已经指出的那样,rustc和LLVM已经完成了整个实现并完全展开了它.实现会根据您想要的字符数而更改.
知道它是否快速的唯一方法是分析.引用llogiq:
我相信通过将前四个点合并为一个可能会更快
movd
我主张在The Real World中测试任何这样的代码.汇编非常重要,尤其是x64/x86_64变体.指令可能有奇怪的管道要求,或者可能导致CPU的其他部分不可用.
个人资料,个人资料!^ _ ^
它并不是真正的高效,它有点糟糕.
const CAP: usize = 64 * 1024;
#[bench]
fn fill_string_repeat(b: &mut Bencher) {
b.iter(|| {
repeat('.').take(CAP).collect::<String>()
});
b.bytes = CAP as u64;
}
#[bench]
fn fill_string_vec(b: &mut Bencher) {
b.iter(|| {
String::from_utf8(vec![b'.'; CAP])
});
b.bytes = CAP as u64;
}
Run Code Online (Sandbox Code Playgroud)
结果:
test fill_string_repeat ... bench: 240,467 ns/iter (+/- 719) = 272 MB/s
test fill_string_vec ... bench: 106,885 ns/iter (+/- 224) = 613 MB/s
Run Code Online (Sandbox Code Playgroud)
该vec!解决方案是更好的,那就是包括UTF-8开销检查,其中占主导地位,使用String::from_utf8_unchecked和获得:
test fill_string_vec_unchecked ... bench: 29,354 ns/iter (+/- 503) = 2232 MB/s
Run Code Online (Sandbox Code Playgroud)
(这里基本上只是memset.)
| 归档时间: |
|
| 查看次数: |
1175 次 |
| 最近记录: |