为什么我的u64 Rust程序在Docker(桌面)中运行速度比原生macOS可执行文件快?

wko9yo5t  于 2023-01-04  发布在  Docker
关注(0)|答案(1)|浏览(167)

这是一个用Rust编写的简单的n次素数程序,实现效率很低,但这不是重点。

use std::time::Instant;

fn main() {
    let n = 10_000;
    let now = Instant::now();
    let nth = nth_prime(n);
    let elapsed = now.elapsed().as_micros();
    println!("prime #{} = {}", n, nth);
    println!("elapsed = {} µs", elapsed);
}

fn nth_prime(n: u64) -> u64 {
    let mut count = 1;
    let mut num = 2;
    while count < n {
        num += 1;
        if is_prime(num) {
            count += 1;
        }
    }
    num
}

fn is_prime(num: u64) -> bool {
    for i in 2..num {
        if num % i == 0 {
            return false;
        }
    }
    true
}

如果我在macOS上使用cargo run --release运行这个程序,我得到的一致执行时间约为3.4秒。然而,如果我在Docker Desktop上运行这个程序(在同一台笔记本电脑上),我得到的一致执行时间约为1.7秒。

FROM rust:1.50
WORKDIR /usr/src/playground
COPY Cargo.toml .
COPY Cargo.lock .
COPY src src
RUN cargo build --release
CMD cargo run --release

但是,如果我将所有u64转换为u32,则本机可执行文件始终在约1.5秒内运行,而Docker版本始终在约1.6秒内运行。
Linux可执行文件的优化方式是否与macOS可执行文件不同?
请注意,我在macOS Big Sur Version 11.2.2和macOS Catalina Version 10.15.17上得到了相同的行为。我在两台笔记本电脑上使用的是Docker Desktop Version 3.1.0和Engine Version 20.10.2,在两台笔记本电脑上使用的是Cargo Version 1.50.0。
另外,请注意,我在Ubuntu 18. 04桌面上尝试了相同的基准测试。对于u64程序,原生Linux可执行文件(cargo run --release)和Docker版本(docker run)都在大约1. 02秒内一致运行。
谢谢!

fivyi3re

fivyi3re1#

这里有点晚,但经历了类似的事情,并发现(至少在我的情况下)性能差异是由于Rust的优化效率较低的旧版本的Docker。
在我的示例中,在执行以下操作之后,我能够获得接近并行的性能:

  • 更新至Docker的最新版本
  • 使能DOCKER_BUILDKIT
  • 对代码应用一些基本优化
  • 缓存生 rust 依赖项(如可能)(here's how和类似的post

相关问题