【问题标题】:Fastest way to get a random number between 1 and 1million in python在python中获取1到100万之间随机数的最快方法
【发布时间】:2018-06-11 01:23:29
【问题描述】:

实现这一目标的绝对最快方法是什么?我每天会做超过 100 万次,所以我想要最大的效率。

使用 numpy(20 次运行后的平均值为 0.0001679009692429128)

t0 = time.clock()
print(np.random.randint(1,1000000))
t1 = time.clock()
print (t1-t0)

随机(平均:0.0000920492372555262)

t2 = time.clock()
print(random.choice(range(1,1000000)))
t3 = time.clock()
print (t3-t2)

令我惊讶的是,random 始终比 numpy 快。有更快的方法吗?

【问题讨论】:

  • 每天一百万次对于一台计算机来说是一个非常小的数字。方法在这里无关紧要。
  • 为什么不生成 100 万个数字,然后在需要时直接读取。
  • 打印的时间比生成随机数的时间要多几个数量级。
  • 调用random.choices(range(1,1000000), k=1000000) 大约需要半秒时间。如果您必须每天这样做一次,那真的不应该成为问题
  • “我想要最高效率”——你可能花在编写时序测试和编写这个问题上的时间比你的 CPU 每天生成一百万个数字所花费的时间还要多,即使你的程序每天运行你的余生。过早的优化不能有效地利用程序员的时间。

标签: python numpy random


【解决方案1】:

numpy 在生成大量随机数样本(数组)时效率更高。例如,

In [10]: %timeit np.random.randint(1,1000000, 1000000)
5.14 ms ± 64.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [11]: %timeit [random.choice(range(1,1000000)) for _ in range(1000000)]
1.01 s ± 14.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

此外,请参阅How can I time a code segment for testing performance with Pythons timeit? 了解如何执行时序测试。当您使用time.clock() 时,您至少应该尝试多次重复该操作,然后计算平均时间。更建议使用timeit 进行定时测试。此外,正如其他人在 cmets 中提到的那样,print() 生成随机数所需的时间明显更长,因此您的时序测试主要是测量print() 的工作速度。相反,您应该这样做:

In [12]: repeat = 1000000
    ...: t0 = time.clock()
    ...: for _ in range(repeat):
    ...:     np.random.randint(1, 1000000)
    ...: t1 = time.clock()
    ...: print((t1 - t0) / repeat)
1.3564629999999908e-06

In [13]: repeat = 1000000
    ...: t2 = time.clock()
    ...: for _ in range(repeat):
    ...:     random.choice(range(1, 1000000))
    ...: t3 = time.clock()
    ...: print((t3 - t2) / repeat)
1.0206699999999956e-06

因此,对于单个数字,numpy 平均只比内置随机数生成器慢 35%。但是,之前的测试表明,在生成大样本时,numpy 的速度明显更快。

【讨论】:

    【解决方案2】:

    我写了一个测试程序。它表明只需 1 秒即可完成您的任务。所以只要写你想要的任何方式,它不会成为你的瓶颈。

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    # Xiang Wang @ 2018-05-23 16:49:00
    
    import time
    import random
    
    start = time.time()
    
    for i in range(1000000):
        random.randint(1, 1000000)
    
    end = time.time()
    
    print("total time: {}".format(end-start))
    

    【讨论】:

      【解决方案3】:

      如果您使用 numpy,使用 random.random_integers 一次生成您需要的所有值会更有效。 python 和 numpy 都使用 Mersenne Twister。更多信息:Differences between numpy.random and random.random in Python

      【讨论】:

        【解决方案4】:

        random.getrandbits 似乎比其他random 模块工具快得多。

        %timeit random.randint(0,1000000)                                                                                                                                                                                                                                     
        799 ns ± 2.45 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
        
        %timeit random.choice(range(0,1000000))                                                                                                                                                                                                                               
        742 ns ± 13.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
        
        %timeit random.getrandbits(20)                                                                                                                                                                                                                                        
        83.9 ns ± 1.61 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
        

        阅读本文以获取更多信息: https://eli.thegreenplace.net/2018/slow-and-fast-methods-for-generating-random-integers-in-python/

        【讨论】:

          猜你喜欢
          • 2016-09-25
          • 2011-01-23
          • 1970-01-01
          • 2011-02-12
          • 2016-01-26
          • 1970-01-01
          • 2011-04-07
          相关资源
          最近更新 更多