如果我在Rust中运行这些基准测试:

#[bench]
fn bench_rnd(b: &mut Bencher) {
    let mut rng = rand::weak_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0));
}

#[bench]
fn bench_ln(b: &mut Bencher) {
    let mut rng = rand::weak_rng();
    b.iter(|| rng.gen_range::<f64>(2.0, 100.0).ln());
}

结果是:

test tests::bench_ln             ... bench:        121 ns/iter (+/- 2)
test tests::bench_rnd            ... bench:          6 ns/iter (+/- 0)

121-6=每ln次通话115纳秒.

但同样的Java基准:

@State(Scope.Benchmark)
public static class Rnd {
    final double x = ThreadLocalRandom.current().nextDouble(2, 100);
}

@Benchmark
public double testLog(Rnd rnd) {
    return Math.log(rnd.x);
}

给我:

Benchmark    Mode Cnt  Score  Error Units
Main.testLog avgt  20 31,555 ± 0,234 ns/op

Rust中的原木速度约为Java中的3.7倍(115/31).

当我测试斜边实现(hypot)时,Rust中的实现速度是Java中的15.8倍.

我是否编写了糟糕的基准测试,或者这是一个性能问题?

回复 comments 中提出的问题:

  1. ","是我国的小数点分隔符.

  2. 我使用cargo bench运行Rust的基准测试,它总是在发布模式下运行.

  3. Java基准测试框架(JavaBenchmarkFramework,JMH) for each 调用创建一个新对象,尽管它是一个static类和一个final变量.如果我在测试方法中添加一个随机创建,我得到43 ns/op.

推荐答案

答案是given by @kennytm:

export RUSTFLAGS='-Ctarget-cpu=native'

解决了这个问题.之后,结果是:

test tests::bench_ln              ... bench:          43 ns/iter (+/- 3)
test tests::bench_rnd             ... bench:           5 ns/iter (+/- 0)

我认为38(±3)足够接近31.555(±0.234).

Rust相关问答推荐

重新导出proc宏导致未解决的extern crate错误""

当两者都有效时,为什么Rust编译器建议添加';&;而不是';*';?

带扫描的铁 rust 使用滤镜

在不重写/专门化整个函数的情况下添加单个匹配手臂到特征的方法?

将数组转换为HashMap的更简单方法

如何实现Serde::Ser::Error的调试

是否提供Bundle 在可执行文件中的warp中的静态文件?

返回迭代器考虑静态生命周期类型

当没有实际结果时,如何在 Rust 中强制执行错误处理?

在 Rust 中忽略 None 值的正确样式

为什么 Rust 字符串没有短字符串优化 (SSO)?

如何递归传递闭包作为参数?

SDL2 没有在终端键上触发?

如何使用 rust bindgen 生成的 std_vector

如果我不想运行析构函数,如何移出具有析构函数的 struct ?

没有通用参数的通用返回

在 Rust 中返回对枚举变体的引用是个好主意吗?

将 (T, ()) 转换为 T 安全吗?

为什么 std::iter::Peekable::peek 可变地borrow self 参数?

如何重写这个通用参数?