如何解决为什么在启用优化的情况下编译,此代码为什么运行得这么快?
我已经在Rust中编码了一种遗传算法,以熟悉Rust。
运行代码时,我发现(cargo run
和(cargo run --release
)版本之间存在极大的性能差异。
我发现创建随机初始化基因的代码对此负责。
我搜索了是否有办法查看由Rust编译器优化的代码,发现在Rust Playground上是可能的。所以我去了,并被一堆汇编代码打招呼,我不知道该怎么读。
以下代码是我提供给Rust操场的代码。 (对不起,代码很脏。我对编程很陌生。)
未经优化(cargo run
)进行编译时,平均需要160秒才能运行。
使用优化程序(cargo run --release
)进行编译时,平均需要3秒钟才能运行。
编译器可能执行哪些导致这种巨大性能差异的确切优化方法?
extern crate rand;
use rand::Rng;
use std::time::Instant;
fn make_genepool(position_list: &Vec<Vec<i8>>,size: i32) -> Vec<Vec<i8>>{
let mut genelist:Vec<Vec<i8>> = Vec::new();
let position_len = position_list.len();
let mut rand = rand::thread_rng();
let mut gene_rand:Vec<Vec<i8>> = Vec::new();
for i in 0..position_len{
let mut gene_insert:Vec<i8> = Vec::new();
let avail_move_len = position_list[i].len();
for _ in 0..size{
gene_insert.push(position_list[i][rand.gen_range(0,avail_move_len)]);
}
gene_rand.push(gene_insert);
}
for i in 0..size as usize{
let mut genelist_insert:Vec<i8> = Vec::new();
for j in 0..position_len{
genelist_insert.push(gene_rand[j][i]);
}
genelist.push(genelist_insert);
}
return genelist;
}
fn main(){
let mut rand = rand::thread_rng();
let mut test_data:Vec<Vec<i8>> = Vec::new();
for i in 0..4520{
let mut temp:Vec<i8> = Vec::new();
for j in 0..rand.gen_range(1,9){
temp.push(rand.gen_range(1,9));
}
test_data.push(temp);
}
let now = Instant::now();
let ans = make_genepool(&test_data,16384);
println!("Time passed: {}",now.elapsed().as_secs_f64());
}
解决方法
您必须比较优化和未优化代码的汇编代码,才能确定其真正作用。
但是可能是:
范围检查:如果您使用常量(例如代码中的4520),则不需要范围检查。
循环展开::如果编译器知道每个循环运行的类型很多,它可能会简单地多次将循环主体转换为相同的代码。
其他诸如内联函数之类的东西。
为使代码运行更快,您可以完全执行编译器的操作,但是最好让编译器来执行。编译器旨在优化您的代码是有原因的。
如果您只想编写更有效的代码,请关注:
-
确保针对用例的算法是最佳的。算法会根据输入的数据执行不同的操作,因此,即使从理论上讲,一种算法可能是最佳的,但对于您的数据来说,您可能会获得最差的性能,而另一种算法可能更合适。
-
了解创建对象,销毁对象等(内存管理)时内部发生的情况。这将要求您学习该语言以了解其对您的作用。但是,编写最高效的代码(使编译器不必猜测)的努力可能不值得您花时间。例如,编译器使用了许多技术,例如分支预测等,这会使您自己变得非常乏味。在代码已经正常工作之后,最好仅在确实需要时进行优化。
最后,这真的值得您花时间吗?专注于使代码正常工作,然后让编译器为您优化代码可能会使您的时间更好。随着时间的流逝,您将通过经验学到东西,并(希望)编写更有效的代码。
如果此答案有帮助,请标记为正确。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。