2012-02-17 2 views
11

파이썬의 itertools 모듈을 사용하여 트리플 중첩 루프의 속도를 높이려고합니다.Python itertools - 천천히?

중첩 루프 시간 = 2.35023 초

Itertools 루프 시간 = 2.67766 초

내가 뭔가를 놓치고 있습니까 : 아래의 테스트 코드는 itertools '제품 방법과 출력을 표준 트리플 중첩 루프를 비교?

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처럼 보인다
+0

"누락 된 것이 있습니까?" - 당신이 놓치고있는 것 중 하나는 'itertools.product()'가 루프를 위해 중첩 된 속도라고하는 사람이 없다는 것입니다. –

+3

@Sven Marnach 9.7. itertools - 효율적인 루핑을위한 반복자를 만드는 함수 ... http : //docs.python.org/library/itertools.html –

답변

9

n의 값 느립니다 : 재미 또한

 
In [40]: print _39 
from itertools import product 

def itertools_product(n): 
    for ijk in product(range(n), repeat=3): 
     pass 

In [41]: %timeit itertools_product(128) 
10 loops, best of 3: 115 ms per loop 

In [42]: %timeit itertools_product(10) 
10000 loops, best of 3: 59.2 us per loop 

In [43]: %timeit itertools_product(300) 
1 loops, best of 3: 1.47 s per loop 

, 지능형리스트 및 발전기 표현 :

 
In [24]: print _23 
from itertools import product 

def nested_loops(n): 
    for i in range(n): 
     for j in range(n): 
      for k in range(n): 
       pass 

def itertools_product(n): 
    for (i,j,k) in product(range(n), repeat=3): 
     pass 


In [25]: %timeit nested_loops(128) 
10 loops, best of 3: 68.6 ms per loop 

In [26]: %timeit itertools_product(128) 
10 loops, best of 3: 162 ms per loop 

In [27]: %timeit nested_loops(10) 
10000 loops, best of 3: 84.5 us per loop 

In [28]: %timeit itertools_product(10) 
10000 loops, best of 3: 79.8 us per loop 

In [30]: %timeit nested_loops(300) 
1 loops, best of 3: 833 ms per loop 

In [31]: %timeit itertools_product(300) 
1 loops, best of 3: 2.07 s per loop 

그리고 튜플 풀기없이 :

 
def list_comprehension_product(n): 
    range_n = range(n) 
    for (i,j,k) in [ (i, j, k) for i in range_n for j in range_n for k in range_n ]: 
     pass 

def generator_expression_product(n): 
    range_n = range(n) 
    for (i,j,k) in ((i, j, k) for i in range_n for j in range_n for k in range_n): 
     pass 

In [51]: %timeit list_comprehension_product(128) 
1 loops, best of 3: 583 ms per loop 

In [52]: %timeit generator_expression_product(128) 
1 loops, best of 3: 480 ms per loop 

이 벤치 마크 python --version 실행했다 : 두 번째 루프는 아마도 때문에 튜플 풀기의 첫 번째보다 느린 것으로 보인다

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

네, 큰 범위에서는 느린 것 같습니다. 바로 그게 바로 당신이 원하는 것이 더 빠릅니다 - 맞습니까? – repoman

5

. 당신은 할 필요가 없습니다, 그리고 그것이 이런 식으로 작업을 수행 할 두 번째 루프 빨리하게 찾을 수 :

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

가, NumPy와 함께 사용하는 대신 전혀 요소를 반복하지 않도록하고 싶어 한 번에 전체 배열에 대해 numpy 작업을 수행합니다. 그렇게하면 루핑 등이 모두 C에서 수행되고 엄청난 속도 향상을 얻을 수 있습니다.

+0

numpy와 관련되지 않기를 바랍니다. 빠른 트리플 인덱싱을 할 수있는 무언가를 가지고 numpy를 사용했습니다. 트리플 인자로 어떤 함수를 호출했을 수도 ... – repoman

관련 문제