2015-07-22 56 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

是的,我猜如果我的功能没有做任何事情,难怪它会这么快!感谢您用这些优秀的例子回答我! –