Performance 如何解释这两个非常相似的函数之间的巨大性能差异?
以下两个功能。它们的区别仅在于迭代器中的减法、强制转换和替换Performance 如何解释这两个非常相似的函数之间的巨大性能差异?,performance,rust,Performance,Rust,以下两个功能。它们的区别仅在于迭代器中的减法、强制转换和替换skipfortake 它们的性能相差5.5倍 fn lehmer_index(xs: [u8; 8]) -> u32 { const FACTORIALS: [u32; 8] = [1, 1, 2, 6, 24, 120, 720, 5040]; (0..8).fold(0, |acc, i| { acc + FACTORIALS[7 - i] * xs.iter().skip(i + 1).fi
skip
fortake
它们的性能相差5.5倍
fn lehmer_index(xs: [u8; 8]) -> u32 {
const FACTORIALS: [u32; 8] = [1, 1, 2, 6, 24, 120, 720, 5040];
(0..8).fold(0, |acc, i| {
acc + FACTORIALS[7 - i] * xs.iter().skip(i + 1).filter(|&&x| x < xs[i]).count() as u32
})
}
fn lehmer_index2(xs: [u8; 8]) -> u32 {
const FACTORIALS: [u32; 8] = [1, 1, 2, 6, 24, 120, 720, 5040];
(0..8).fold(0, |acc, i| {
acc + FACTORIALS[7 - i] * ((xs[i] as u32) - xs.iter().take(i).filter(|&&x| x < xs[i]).count() as u32)
})
}
在我的模拟中,我计算了数万亿次,这是一个巨大的差异。我会使用第一个,但第二个是一个广义的版本,它使用的是我需要的假设较少的输入
为什么会有速度差?我如何解释这样的性能差异呢?第一个代码看起来是完全内联和展开的矢量化代码,而第二个代码使优化器跳闸,因此无法展开循环
没有任何真正的方法可以从锈迹代码中对此进行推理,您需要提取生成的程序集和现代x86处理器的直觉。然后试着修改代码,直到优化器生成符合基准的东西
在特定情况下(对于rust 1.47),通过将内部值指定给变量,简单地重新排序表达式似乎会导致线性组装,这在您的基准测试中可能会被证明是非常好的:
lehmer_index time: [8.4142 ns 8.4796 ns 8.5542 ns]
lehmer_index2 time: [46.726 ns 46.812 ns 46.921 ns]
pub fn lehmer_index3(xs:[u8;8])->u32{
常量阶乘:[u32;8]=[1,1,2,6,24,120,720,5040];
(0..8).折叠(0,| acc,i |{
设a=xs[i]为u32;
设b=xs.iter()
.采取(i)
.filter(|和&x | x
谢谢。不幸的是,这似乎对我的基准测试没有任何影响。