【发布时间】:2021-04-22 10:02:23
【问题描述】:
我在 Java 和 Rust 上运行了一个小型相同的基准测试。
Java:
public class Main {
private static final int NUM_ITERS = 100;
public static void main(String[] args) {
long tInit = System.nanoTime();
int c = 0;
for (int i = 0; i < NUM_ITERS; ++i) {
for (int j = 0; j < NUM_ITERS; ++j) {
for (int k = 0; k < NUM_ITERS; ++k) {
if (i*i + j*j == k*k) {
++c;
System.out.println(i + " " + j + " " + k);
}
}
}
}
System.out.println(c);
System.out.println(System.nanoTime() - tInit);
}
}
生锈:
use std::time::SystemTime;
const NUM_ITERS: i32 = 100;
fn main() {
let t_init = SystemTime::now();
let mut c = 0;
for i in 0..NUM_ITERS {
for j in 0..NUM_ITERS {
for k in 0..NUM_ITERS {
if i*i + j*j == k*k {
c += 1;
println!("{} {} {}", i, j, k);
}
}
}
}
println!("{}", c);
println!("{}", t_init.elapsed().unwrap().as_nanos());
}
当NUM_ITERS = 100 时,Rust 的表现如预期的那样优于 Java
Java: 59311348 ns
Rust: 29629242 ns
但是对于 NUM_ITERS = 1000,我发现 Rust 需要更长的时间,而 Java 更快
Java: 1585835361 ns
Rust: 28623818145 ns
这可能是什么原因?在这种情况下,Rust 不应该比 Java 表现更好吗?还是因为我在执行中犯了一些错误?
更新
我从代码中删除了 System.out.println(i + " " + j + " " + k); 和 println!("{} {} {}", i, j, k); 行。这是输出
NUM_ITERS = 100
Java: 3843114 ns
Rust: 29072345 ns
NUM_ITERS = 1000
Java: 1014829974 ns
Rust: 28402166953 ns
因此,如果没有 println 语句,Java 在这两种情况下的性能都比 Rust 好。我只是想知道为什么会这样。 Java 运行垃圾收集器和其他开销。我在 Rust 中没有最佳地实现循环吗?
【问题讨论】:
-
你是在生产模式还是在调试模式下编译rust?
-
不存在每次迭代产生输出的基准。您测量的是 I/O,而不是 CPU 时间。
-
虽然在测量过程中打印任何东西绝对不好,但我认为上面的评论者忽略了这样一个事实,即在 100 万个测试组合中,只有 299 次满足条件
a2 + b2 = c2(使用 NUM_ITERS = 100)。 -
@DivyanshuPundir,在 IntelliJ 中,使用
cargo run --release运行以运行优化代码。 -
我刚刚使用了一个改进的版本(如果重新打开,我很乐意分享一个答案),优化 Rust 构建的结果是每次迭代 0.6 ns,对于 Java 是 0.32 ns每次迭代。我不觉得这是一个令人惊讶的结果,这里没有分配所以 GC 无关紧要,Java 的 JIT 编译器非常擅长优化这样的简单代码。
标签: java performance rust