Fél*_*ger 10 macos rust docker
这是一个用 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
}
Run Code Online (Sandbox Code Playgroud)
如果我在 macOS 上使用 本地运行这个程序cargo run --release,我会得到大约 3.4 秒的一致执行时间。但是,如果我使用 Docker Desktop(在同一台笔记本电脑上)运行这个程序,我会得到大约 1.7 秒的一致执行时间。这是我正在使用的 Dockerfile:
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
Run Code Online (Sandbox Code Playgroud)
但是,如果我将所有u64s切换为u32s,那么本机可执行文件会在约 1.5 秒内持续运行,而 Docker 版本会在约 1.6 秒内持续运行。
Linux 可执行文件是否以 macOS 可执行文件没有的方式进行了优化?
请注意,我在 macOS Big Sur 版本 11.2.2 和 macOS Catalina 版本 10.15.17 上得到了相同的行为。我在两台笔记本电脑上使用 Docker 桌面版本 3.1.0 和引擎版本 20.10.2,我在两台笔记本电脑上使用 Cargo 版本 1.50.0。
另请注意,我在 Ubuntu 18.04 桌面上尝试了相同的基准测试。本机 Linux 可执行文件 ( cargo run --release) 和 Docker 版本 ( docker run) 都在大约 1.02 秒内为u64程序一致运行。
谢谢!
MacOS 并不真正运行 docker,因此在运行 docker 时,您还运行一个 Linux 虚拟机来托管 docker 容器。该虚拟机可能正在使用 stable-x86_64-unknown-linux-gnu (因为这是 docker 镜像所期望的),而您的本机主机是其他目标。
您可以运行rustup show以查看本机主机上的活动工具链。我的猜测是,它可能是一个相当通用的 mac 工具链,与广泛的硬件兼容,而您的实际 mac 可能相当现代,因此您的硬件可能支持 LLVM 优化器(生锈的编译器后端)的一系列优化使用)不要“不敢”为您启用。
也许RUSTFLAGS="-C target-cpu=native"在发布模式下再次构建之前进行设置会提高性能?或者也许以某种方式运行一个完全不同的目标?
所以,主要问题是:您正在编译什么目标,以及您在什么实际硬件上运行?
附录:这个问题很久以前就被问过。也许 rust 1.50 中使用的 LLVM 不太擅长针对 mac 进行优化,只需更新到当前的 rust 版本,情况就会变得更好?