【问题标题】:How can I speed up this two-lines code?我怎样才能加快这个两行代码?
【发布时间】:2017-03-13 20:14:36
【问题描述】:

我需要加速下面的代码:

for i in range(0, 2**N):

    output[i] = f(np.array(map(int, bin(i)[2:].zfill(N))))

N 大约是30,所以代码很慢(在我的笔记本电脑上大约需要 33 小时)。函数f() 的参数是索引i 的二进制表示,f() 可以是任意向量化函数。我不是专家,但为了加快代码速度,我想摆脱for 循环,这意味着我需要对f() 的参数进行矢量化处理。换句话说,我必须用从02**N 的数字的二进制表示创建一个矩阵。这可以通过以下代码实现:

list(itertools.product([0, 1], repeat=N))

我在this link 找到的。但是,在我看来itertools 非常慢,显然它需要大量内存,因为2**30 大约是十亿。

您对加快此代码的速度有什么建议吗?提前致谢。

【问题讨论】:

  • 除了output 的最后一个值之外,您似乎正在丢弃所有值。
  • 与其生成十亿元素数组,不如重写为生成器?
  • 查找生成器和yield 命令。
  • 另外,如果您使用的是 Python 2.7,请务必使用 "xrange" ,而不是 "range" - 仅此一项就会在系统内存中创建 2 ^30 个对象。
  • 你真的在使用所有十亿的值吗?你能在调用时生成每个值和then store that value if it is called again吗?

标签: python performance loops


【解决方案1】:

总是简介:

>>> timeit.timeit("for i in range(0, 2**N): numpy.array(map(int, bin(i)[2:].zfill(N)))", "import numpy; N=5", number=100000)
26.472519159317017
>>> timeit.timeit("for t in itertools.product((0, 1), repeat=N): numpy.array(t)", "import numpy, itertools; N=5", number=100000)
6.129688024520874

您可以看到itertools.product 方法要快得多,因为它不必摆弄字符串。

问题可能是大部分时间都花在了f 函数上。

另一种解决方案是让f 接受一个整数,并将其用作二进制字段。

【讨论】:

  • 另外:在最近的 MBP 上进行 2^24 pass 操作的时间:883 毫秒,仅 range,501 毫秒,xrange,1.92 秒,对 pass 和 @987654329 的函数调用@, 函数调用 1.58s + xrange.
  • 酷,我尝试使用N=20,它需要 1 分钟而不是 1.5 分钟。这将为更大的N 节省大量时间。我猜N=30 是 22 小时,而 33 小时。
猜你喜欢
  • 2021-11-21
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2021-07-31
相关资源
最近更新 更多