Python 3.x 使用冻结的rv分发对象来加速具有许多函数调用的程序,其中使用了相同的分发?
问题 假设有一个程序需要在不同时间从不同函数和类中的相同分布生成大量随机变量。 使用冻结的rv分布对象(并将该对象拖动到所有函数中)似乎比在绘制随机变量之前在每个函数中重新生成分布要快得多Python 3.x 使用冻结的rv分发对象来加速具有许多函数调用的程序,其中使用了相同的分发?,python-3.x,random,scipy,distribution,Python 3.x,Random,Scipy,Distribution,问题 假设有一个程序需要在不同时间从不同函数和类中的相同分布生成大量随机变量。 使用冻结的rv分布对象(并将该对象拖动到所有函数中)似乎比在绘制随机变量之前在每个函数中重新生成分布要快得多 给出一些证据:考虑这个代码: import scipy.stats import time def gen_rvs(dist): dist.rvs(1000) time1 = time.time() d = scipy.stats.bernoulli(0.75) for i in range(10
给出一些证据:考虑这个代码:
import scipy.stats
import time
def gen_rvs(dist):
dist.rvs(1000)
time1 = time.time()
d = scipy.stats.bernoulli(0.75)
for i in range(100000):
gen_rvs(d)
print(time.time() - time1)
运行速度(在我的机器上)几乎是此速度的10倍(7.4秒vs.68.6秒):
潜在解决方案
- 通过所有函数等拖动分布对象。?问题:这看起来非常混乱,需要更多的参数(如果您可能需要多个发行版),使得函数调用不容易理解,并且更容易出错
- 是否将冻结的rv分布对象作为全局变量?问题:如果程序分布在多个文件中,则无法轻松工作。并行化会产生更多的问题
- 将冻结的rv分布传递给在某个点需要rv发生器的所有类别,并将其保存到任何地方?问题:看起来仍然很混乱
- 将生成的随机变量而不是分布传递给函数?问题:如果有更长的调用堆栈,则会更加混乱。必须事先知道一个特定函数需要多少随机变量
- 在单独的进程中运行随机数生成器,并将随机变量推送到队列中,其他进程从队列中收集这些变量?问题:虽然这听起来很花哨,也不凌乱,但实现它并有效地控制流程应该生成多少随机变量可能会变得凌乱
import scipy.stats
import time
def gen_rvs():
scipy.stats.bernoulli(0.75).rvs(1000)
time1 = time.time()
for i in range(100000):
gen_rvs()
print(time.time() - time1)