近日 B 站看到概率问题:《连续抛 10000 次硬币,最多几连正的概率最大?》
使用擅长的 Java 模拟,共 10w 次实验,每次实验模拟投掷 1w 次,耗时 1080ms ;多次运行耗时相差不大。
同样的算法,用 Kimi 翻译成 Rust ,cargo build --release 生成可执行文件;但执行效率不如 Java ,且耗时 10x。
哪里有问题呢?
public class TossStreakProbability {
public static final int tosses = 10_000; // 10^4
public static final int iterations = 100_000; // 10^5
public static void main(String[] args) {
Instant start = Instant.now();
Map<Integer, Long> streakMap = new HashMap<>();
for (int i = 0; i < iterations; i++) {
int maxStreak = maxStreak();
streakMap.put(maxStreak, streakMap.getOrDefault(maxStreak, 0L) + 1);
}
long total = streakMap.values().stream().mapToLong(Long::intValue).sum();
streakMap.forEach((key, value) -> System.out.printf(
"Max: %d, count: %d, percent:%.2f%%\n",
key, value, (value * 100.0) / total));
// print execute time in ms
System.out.println("Execution time: " + (Instant.now().toEpochMilli() - start.toEpochMilli()) + "ms");
}
public static int maxStreak() {
int streak = 0, maxStreak = 0;
var random = ThreadLocalRandom.current();
for (int i = 0; i < tosses; i++) {
boolean current = random.nextBoolean();
if (current) {
streak++;
} else {
streak = 0;
}
maxStreak = Math.max(maxStreak, streak);
}
return maxStreak;
}
}
use std::collections::HashMap;
use std::time::Instant;
use rand::prelude::*;
const TOSSES: i32 = 10_000; // 10^4
const ITERATIONS: i32 = 100_000; // 10^5
fn main() {
let start = Instant::now();
let mut streak_map: HashMap<i32, i64> = HashMap::new();
for _ in 0..ITERATIONS {
let max_streak = max_streak();
*streak_map.entry(max_streak).or_insert(0) += 1;
}
let total: i64 = streak_map.values().sum();
for (key, value) in &streak_map {
println!("Max: {}, count: {}, percent: {:.2}%", key, value, (*value as f64 / total as f64) * 100.0);
}
// print execute time in ms
let duration = start.elapsed();
println!("Execution time: {}ms", duration.as_millis());
}
fn max_streak() -> i32 {
let mut streak = 0;
let mut max_streak = 0;
let mut rand = thread_rng();
for _ in 0..TOSSES {
let current = rand.gen_bool(0.5);
if current {
streak += 1;
} else {
streak = 0;
}
max_streak = std::cmp::max(max_streak, streak);
}
max_streak
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.