2016-07-08 40 views
1

我想知道是否有人能夠幫助我理解爲什麼以下兩個程序以明顯不同的速度運行(第一個以1/10秒爲單位,第二個以3秒爲單位)。瞭解numpy數組的運行時間嗎?

def gaussian(x, h, m, c): 
    return list(h * exp(-(x-m)**2/(2*c**2))) 

x = np.linspace(0, 1000, 1001) 

for i in range(1000): 
    gaussian(x, 50, 500, 10) 

def gaussian2(x, h, m, c): 
    def computer(x): 
     return h * exp(-(x-m)**2/(2*c**2)) 
    y = [] 
    for val in x: 
     y.append(computer(val)) 
return y 

x = np.linspace(0, 1000, 1001) 

for i in range(1000): 
    gaussian2(x, 50, 500, 10) 

我需要第二個版本的唯一原因是因爲它讓我看看列表中的所有元素,所以我可以用它們來進行其它操作(在未示出這個例子)。但這不是我所要求的 - 我在問爲什麼第二種形式比第一種慢得多。

謝謝!

+3

因爲(假設'exp'函數是從numpy導入的)第一個函數與向量化數據(向量/數組/列/等)一起工作,第二個函數與標量值一起工作。 numpy中的大多數向量化操作都是使用Cython實現的,與其標量替代方法相比,__much__更快... – MaxU

+0

是'exp''np.exp'還是'math.exp'? – hpaulj

回答

1

MaxU是正確的,主要原因是numpy中的向量化數學比Python中的標量數學更快。然而,記住循環遍歷一個numpy數組的性能要比循環遍歷一個Python列表要重要。它並不顯示儘可能多的在這種情況下,數學,但也有其他情況下,它可以是主要因素放緩

import numpy as np 
import math 

def gaussian(x, h, m, c): 
    return list(h * np.exp(-(x-m)**2/(2*c**2))) 

def gaussian2(x, h, m, c): 
    def computer(x): 
     return h * math.exp(-(x-m)**2/(2*c**2)) 
    y = [] 
    for val in x: 
     y.append(computer(val)) 
    return y 

x = np.linspace(0, 1000, 1001) 
x_list = x.tolist() 

%timeit gaussian(x, 50, 500, 10) 
%timeit gaussian2(x, 50, 500, 10) 
%timeit gaussian2(x_list, 50, 500, 10) 

產量:

10000 loops, best of 3: 114 µs per loop 
100 loops, best of 3: 2.97 ms per loop 
100 loops, best of 3: 2.35 ms per loop 

所以其清晰的最大瓶頸是數學,但與列表相比,循環numpy數組有一點放緩。