【发布时间】:2019-03-28 10:45:30
【问题描述】:
代码很幼稚:
use std::time;
fn main() {
const NUM_LOOP: u64 = std::u64::MAX;
let mut sum = 0u64;
let now = time::Instant::now();
for i in 0..NUM_LOOP {
sum += i;
}
let d = now.elapsed();
println!("{}", sum);
println!("loop: {}.{:09}s", d.as_secs(), d.subsec_nanos());
}
输出是:
$ ./test.rs.out
9223372036854775809
loop: 0.000000060s
$ ./test.rs.out
9223372036854775809
loop: 0.000000052s
$ ./test.rs.out
9223372036854775809
loop: 0.000000045s
$ ./test.rs.out
9223372036854775809
loop: 0.000000041s
$ ./test.rs.out
9223372036854775809
loop: 0.000000046s
$ ./test.rs.out
9223372036854775809
loop: 0.000000047s
$ ./test.rs.out
9223372036854775809
loop: 0.000000045s
程序几乎立即结束。我还使用 for 循环在 C 中编写了一个等效代码,但它运行了很长时间。我想知道是什么让 Rust 代码如此之快。
C 代码:
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
double time_elapse(struct timespec start) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return now.tv_sec - start.tv_sec +
(now.tv_nsec - start.tv_nsec) / 1000000000.;
}
int main() {
const uint64_t NUM_LOOP = 18446744073709551615u;
uint64_t sum = 0;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
for (int i = 0; i < NUM_LOOP; ++i) {
sum += i;
}
double t = time_elapse(now);
printf("value of sum is: %llu\n", sum);
printf("time elapse is: %lf sec\n", t);
return 0;
}
Rust 代码使用-O 编译,C 代码使用-O3 编译。 C 代码运行速度很慢,还没有停止。
在修复了 visibleman 和 Sandeep 发现的错误后,两个程序几乎立即打印了相同的数字。我试图将NUM_LOOP 减一,考虑到溢出,结果似乎是合理的。此外,使用NUM_LOOP = 1000000000,两个程序都不会溢出并立即产生正确的答案。这里使用了哪些优化?我知道我们可以使用像(0 + NUM_LOOP - 1) * NUM_LOOP / 2 这样的简单方程来计算结果,但我不认为这种计算是由编译器在溢出情况下完成的......
【问题讨论】:
-
除了
-O3,还值得添加-Wall -Wextra
标签: c rust llvm-codegen