【问题标题】:Python itertools - slow?Python itertools - 慢?
【发布时间】:2012-02-17 23:09:31
【问题描述】:

我正在尝试使用 Python 的 itertools 模块来加速三重嵌套 for 循环。下面的测试代码将标准的三重嵌套循环与 itertools 的产品方法和输出进行比较:

嵌套循环时间 = 2.35023 秒

Itertools 循环时间 = 2.67766 秒

我错过了什么吗?

import numpy
import itertools
import time

n = 128
a = numpy.arange(n**3).reshape((n,n,n))
b = numpy.zeros((n,n,n))
c = numpy.zeros((n,n,n))

t = time.time()
for i in range(n):
    for j in range(n):
        for k in range(n):
            b[i,j,k] = a[i,j,k]
print 'Nested loop time = %g secs' % (time.time() - t)

t = time.time()
for (i,j,k) in itertools.product(range(n), repeat=3):
    c[i,j,k] = a[i,j,k]
print 'Itertools loop time = %g secs' % (time.time() - t)

【问题讨论】:

  • “我错过了什么吗?” -- 你似乎缺少的是没有人声称itertools.product() 的想法是加速嵌套 for 循环-
  • @Sven Marnach 9.7。 itertools — 为高效循环创建迭代器的函数...docs.python.org/library/itertools.html

标签: python loops


【解决方案1】:

对于较大的n 值,itertools.product 似乎确实比较慢:

在 [24] 中:打印 _23 从 itertools 导入产品 def 嵌套循环(n): 对于范围内的 i (n): 对于范围(n)中的j: 对于范围(n)中的k: 经过 定义 itertools_product(n): 对于产品(范围(n),重复= 3)中的(i,j,k): 经过 在 [25] 中:%timeit 嵌套循环(128) 10 个循环,3 个循环中的最佳:每个循环 68.6 毫秒 在 [26] 中:%timeit itertools_product(128) 10 个循环,3 个循环中的最佳:每个循环 162 毫秒 在 [27] 中:%timeit nested_loops(10) 10000 次循环,最佳 3 次:每个循环 84.5 us 在 [28] 中:%timeit itertools_product(10) 10000 次循环,最好的 3 次:每个循环 79.8 us 在 [30] 中:%timeit nested_loops(300) 1 个循环,最好的 3 个:每个循环 833 毫秒 在 [31] 中:%timeit itertools_product(300) 1 个循环,最好的 3 个:每个循环 2.07 秒

并且没有元组解包:

在 [40] 中:打印 _39 从 itertools 导入产品 定义 itertools_product(n): 对于产品中的 ijk(范围(n),重复 = 3): 经过 在 [41] 中:%timeit itertools_product(128) 10 个循环,3 个循环中的最佳:每个循环 115 毫秒 在 [42] 中:%timeit itertools_product(10) 10000 次循环,最好的 3 次:每个循环 59.2 us 在 [43] 中:%timeit itertools_product(300) 1 个循环,最好的 3 个:每个循环 1.47 秒

另外,为了好玩,列表推导和生成器表达式:

def list_comprehension_product(n): range_n = 范围(n) for (i,j,k) in [ (i, j, k) for i in range_n for j in range_n for k in range_n ]: 经过 def generator_expression_product(n): range_n = 范围(n) for (i,j,k) in ( (i, j, k) for i in range_n for j in range_n for k in range_n ): 经过 在 [51] 中:%timeit list_comprehension_product(128) 1 个循环,最好的 3 个:每个循环 583 毫秒 在 [52] 中:%timeit generator_expression_product(128) 1 个循环,最好的 3 个:每个循环 480 毫秒

这些基准测试是使用python --version 运行的:

2.6.7 (r267:88850, Jul 31 2011, 19:30:54)
[GCC 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2335.15.00)]

【讨论】:

  • 是的,对于大范围来说,它似乎确实比较慢。这正是您希望它更快的地方 - 对吧?
【解决方案2】:

似乎第二个循环比第一个慢,可能是因为元组解包。您不必这样做,我发现这样做可以使第二个循环更快:

for ijk in itertools.product(range(n), repeat=3):
    c[ijk] = a[ijk]

当然,使用 numpy,您希望完全避免循环遍历元素,而是一次对整个数组使用 numpy 操作。这样一来,所有循环等都在 C 中完成,您将获得巨大的加速。

【讨论】:

  • 不希望这与 numpy 相关。只是使用 numpy 来获得一些允许快速三重索引的东西。可能是使用三重参数调用某个函数...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多