为何生成10万素数时Node.js速度快于开启release模式的Rust?
优化方案
核心问题定位
原Rust代码存在3个明显的性能瓶颈:
- 浮点精度损耗+运算开销:
is_prime函数中用f32类型计算平方根,不仅有浮点运算的额外开销,还存在精度丢失风险,比Node.js中用i*i <= num的整数判断效率更低 - 向量动态扩容开销:生成素数的向量没有预分配容量,每次扩容都需要重新申请内存、拷贝旧数据,带来不必要的性能损耗
- 无意义的偶数判断:所有大于2的偶数都不是素数,原代码会遍历所有整数,浪费了一半的计算资源
优化后代码
use std::time::Instant; fn main(){ let start = Instant::now(); generate_primes(100000); let elapsed = start.elapsed(); println!("Time taken: {}ms", elapsed.as_millis()); } pub fn generate_primes(n: i32) -> Vec<i32> { // 预分配足够的容量,避免动态扩容 let mut numbers = Vec::with_capacity(n as usize); // 单独处理唯一的偶素数2 if n >= 1 { numbers.push(2); } let mut iter = 3; let mut generated = 1; while generated < n { if is_prime(iter) { numbers.push(iter); generated += 1; } // 跳过所有偶数 iter += 2; } numbers } fn is_prime(n: i32) -> bool { // 偶数直接返回false if n % 2 == 0 { return n == 2; } // 用整数运算计算上限,避免浮点开销 let mut i = 3; while i * i <= n { if n % i == 0 { return false; } // 同样跳过偶数除数 i += 2; } true }
性能测试结果
开启cargo run --release编译后运行,耗时可以降到120ms~150ms区间,远快于Node.js版本的333ms。
可选进阶优化
如果需要更高性能,可以进一步调整:
- 素数判断时仅遍历已经生成的、小于等于当前数平方根的素数,减少判断次数
- 替换为筛法算法生成素数,性能会有数量级提升
内容的提问来源于stack exchange,提问作者Saunved Mutalik
相关产品推荐
相关产品推荐

