2015-07-22 54 views
0

我想(當然和正確性,)優化這段代碼的速度只有在python3:Python3,地圖功能

from math import log 
from timeit import Timer 

def groffle_slow(mass, density): 
    total = 0.0 
    for i in range(10000): 
     masslog = log(mass * density) 
     total += masslog/(i+1) 
    return total 

我在多少map速度東西深感震驚,所以...

def groffle_faster(mass, density): 
    total = 0.0 
    masslog = log(mass * density) 
    return map(sum, (masslog/(i+1) for i in range(10000))) 

看着執行時間的差異,沒有比較。 groffle_faster()的速度更快,但它返回一個地圖對象。地圖對象應該包含作爲浮點數的和。

無論如何,我可以浮出地圖對象?

謝謝!

回答

3

因爲它沒有做任何事情,它的速度更快;如果是的話,它將無法工作。

>>> mass = 1.2 
>>> density = 2.3 
>>> masslog = math.log(mass * density) 
>>> map(sum, (masslog/(i+1) for i in range(10000))) 
<map object at 0x7feccaf1fc18> 

map對象是懶對象這將產生施加到可迭代,在這種情況下是發電機表達(masslog/(i+1) for i in range(10000))的每個元素功能sum的結果。沒有計算完成。

但這並不這裏太大的意義,無論如何,因爲你想給sum功能應用到每個元素單獨等:

>>> list(map(sum, (masslog/(i+1) for i in range(10000)))) 
Traceback (most recent call last): 
    File "<ipython-input-13-c0f9c805843a>", line 1, in <module> 
    list(map(sum, (masslog/(i+1) for i in range(10000)))) 
TypeError: 'float' object is not iterable 

你真正想要的是什麼根本

>>> sum(masslog/(i+1) for i in range(10000)) 
9.936677928893602 

這將使

>>> %timeit groffle_slow(1.5, 2.5) 
100 loops, best of 3: 5.08 ms per loop 
>>> %timeit groffle_fast(1.5, 2.5) 
100 loops, best of 3: 3.02 ms per loop 

但由於sum(1/(i+1) for i in range(10000))是一個固定的數字,我不知道你爲什麼不乾脆用類似

>>> def groffle_O1(mass, density): 
...  MSUM = 9.787606036044345 
...  return log(mass*density) * MSUM 
... 
>>> %timeit groffle_O1(1.5, 2.5) 
1000000 loops, best of 3: 424 ns per loop 

但是你沒有指定你真的下運行哪些約束,所以很難知道你真正的問題是什麼。

+0

是的,我猜如果我的功能沒有做任何事情,難怪它會這麼快!感謝您用這些優秀的例子回答我! –