-6 performance go rust llvm-codegen
我有两个(相当于?)程序,一个在另一个在Rust中.平均执行时间是:
走
package main
import (
"fmt"
"time"
)
func main() {
work := []float64{0.00, 1.00}
start := time.Now()
for i := 0; i < 100000000; i++ {
work[0], work[1] = work[1], work[0]
}
elapsed := time.Since(start)
fmt.Println("Execution time: ", elapsed)
}
Run Code Online (Sandbox Code Playgroud)
锈
我编译了 --release
use std::time::Instant;
fn main() {
let mut work: Vec<f64> = Vec::new();
work.push(0.00);
work.push(1.00);
let now = Instant::now();
for _x in 1..100000000 {
work.swap(0, 1);
}
let elapsed = now.elapsed();
println!("Execution time: {:?}", elapsed);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Rust的性能是否低于Go?Rust程序是否可以用惯用的方式编写,以便更快地执行?
Rust程序是否可以用惯用的方式编写,以便更快地执行?
是.要创建包含少量元素的向量,请使用以下vec![]宏:
let mut work: Vec<f64> = vec![0.0, 1.0];
for _x in 1..100000000 {
work.swap(0, 1);
}
Run Code Online (Sandbox Code Playgroud)
那么这段代码更快吗?是.看看生成的程序集:
example::main:
mov eax, 99999999
.LBB0_1:
add eax, -11
jne .LBB0_1
ret
Run Code Online (Sandbox Code Playgroud)
在我的电脑上,这比原始代码快30倍.
为什么程序集仍然包含无效的循环?为什么编译器不能看到两个pushes是相同的vec![0.0, 1.0]?两个非常好的问题都可能指向LLVM或Rust编译器中的缺陷.
然而,遗憾的是,从微观基准中获得的信息并不多.基准测试很难,就像真的很难.甚至专业人士都有很多陷阱.在您的情况下,基准测试在几个方面存在缺陷.首先,你永远不会观察到矢量的内容(它从未使用过).这就是为什么一个好的编译器可以删除所有甚至触及向量的代码(正如Rust编译器在上面所做的那样).所以这不好.
除此之外,这与任何真正的性能关键代码都不相似.即使稍后会观察到矢量,交换奇数次也等于单次交换.所以除非你想看看优化器能否理解这个交换规则,遗憾的是你的基准测试并不是真的有用.