You need to enable JavaScript to run this app. Python 3.8 骰子模拟项目大参数输入时随机数生成速度过慢问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.8 骰子模拟项目大参数输入时随机数生成速度过慢问题咨询

骰子投掷程序运行缓慢的原因与优化方案

核心性能瓶颈

  • 高频控制台I/O是最大的性能杀手:原代码每完成一次投掷就执行一次print("Throw ", i, " of ", nt),控制台输出是系统级阻塞I/O操作,当投掷次数达到上万次时,这部分操作占用的时间会远高于计算本身的耗时,绝大多数场景下的卡顿都来源于此。
  • 逐次调用随机数函数的固定开销极高:原代码对每一次投掷、每一个骰子都单独调用random.randint(1,6),单次Python函数调用的固定开销不低,当总随机数调用次数达到数十万乃至上百万次时,光函数调用的额外开销就会消耗大量时间。
  • 存在完全无意义的冗余计算:代码生成完所有投掷结果后,额外对整个结果列表做了全量排序(sums.sort()),但后续用Counter统计频率完全不需要输入列表是有序的,这步操作在大列表上会带来不必要的O(n log n)时间开销。
  • 循环结构效率极低:原代码用两层while循环手动维护计数器c、循环变量i、累计值sum,没有利用Python内置的循环迭代能力,解释器层面的执行效率很低;同时变量名sum、max、min和Python内置函数重名,会额外增加解释器的名称查找开销。

针对性优化方案

  • 调整日志打印逻辑:去掉单次投掷就打印一次进度的写法,要么完全关闭过程打印,要么每完成固定比例(比如1%)的投掷任务再输出一次进度,把高频I/O的开销降到可忽略的水平。
  • 替换随机数生成逻辑:优先用NumPy的向量化随机数生成能力,一次性生成所有投掷需要的骰子结果、直接沿轴求和,整个过程在C语言层面执行,没有Python层的循环和函数调用开销,性能可以提升100~1000倍。如果不依赖NumPy,也可以把两层while循环替换为Python生成器表达式的循环结构,减少手动维护变量的开销。
  • 删除冗余计算:直接移除sums.sort()代码,统计频率、计算最大最小值都可以在无序列表上完成,不需要预先排序。
  • 修正变量命名冲突:把临时变量sum改名为total,max、min改名为res_max、res_min,避免遮蔽Python内置函数带来的性能损耗。

可参考的优化实现

高性能NumPy版本(适合大参数场景)

import numpy as np
import matplotlib.pyplot as plt

nd = int(input("Insert number of dice: "))
nt = int(input("Insert number of throws: "))
print(f"{nd} dice thrown {nt} times")
print("Generating sums, please hold....")

# 一次性生成所有骰子结果,向量化求和
all_dice = np.random.randint(1, 7, size=(nt, nd))
sums = all_dice.sum(axis=1)

# 直接计算极值
res_max = sums.max()
res_min = sums.min()
print(f"||Maximum result: {res_max} ||Minimum result: {res_min}")

# 用bincount做频率统计,比Counter速度更快
freq = np.bincount(sums)
y = np.nonzero(freq)[0]
x = freq[y]

print("Rappresenting results")
plt.plot(y, x)
plt.xlabel("Risultati")
plt.ylabel("Frequenza")
plt.title("Distribuzione delle somme")
plt.grid(True)
plt.tight_layout()
plt.show()

纯Python无依赖版本(优化后比原代码快3~5倍)

import random
from collections import Counter
import matplotlib.pyplot as plt

nd = int(input("Insert number of dice: "))
nt = int(input("Insert number of throws: "))
print(f"{nd} dice thrown {nt} times")
print("Generating sums, please hold....")

sums = [sum(random.randint(1,6) for _ in range(nd)) for _ in range(nt)]

res_max = max(sums)
res_min = min(sums)
print(f"||Maximum result: {res_max} ||Minimum result: {res_min}")

freq_counter = Counter(sums)
y = list(freq_counter.keys())
x = list(freq_counter.values())

print("Rappresenting results")
plt.plot(y, x)
plt.xlabel("Risultati")
plt.ylabel("Frequenza")
plt.title("Distribuzione delle somme")
plt.grid(True)
plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者Mario Scuderi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.12 18:15:07