0

私は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() はかなり高速ですが、マップ オブジェクトを返します。マップ オブジェクトには、合計が float として含まれている必要があります。

とにかく、マップオブジェクトからフロートを取得できますか?

ありがとう!

4

1 に答える 1

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オブジェクトは、イテラブルの各要素(この場合はジェネレータ式) にsum適用された関数の結果を生成する遅延オブジェクトです。計算は行われていません。(masslog/(i+1) for i in range(10000))

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

しかし、実際に操作している制約を指定していないため、実際の問題が何であるかを知るのは困難です。

于 2015-07-22T00:19:54.537 に答える