2

Python では、理論的には、 と のうちどちらのメソッドが高速である必要がありますか( の値が同じであると仮定しますtest1) 。使用してみましたが、違いはほとんどありません。test2x%timeit

import numpy as np

class Tester():

    def __init__(self):
        self.x = np.arange(100000)

    def test1(self):
        return np.sum(self.x * self.x )

    def test2(self,x):
        return np.sum(x*x)
4

2 に答える 2

7

Python のどの実装でも、時間はそれぞれ 100,000 要素を持つ 2 つのベクトルの乗算によって圧倒的に支配されます。それに比べれば、それ以外はすべてノイズです。他のオーバーヘッドを測定することに本当に関心がある場合は、ベクトルをはるかに小さくしてください。

CPython では、test2()おそらく少し速くなります。「余分な」引数がありますが、引数は「C の速度で」展開されるため、それほど重要ではありません。LOAD_FAST引数は、単純なアクセスであるオペコードを介して、ローカル変数と同じ方法でアクセスされarray[index]ます。

ではtest1()、 の各インスタンスself.xにより、文字列「x」がディクショナリで検索されself.__dict__ます。これは、インデックス付き配列アクセスよりも低速です。しかし、長々とした掛け算にかかる時間と比べると、基本的には何でもありません。

于 2013-11-03T22:05:27.387 に答える
1

この種の質問は質問の要点を逃していることは知っていますが、質問にタグを付けてnumpy、大きな配列の速度の違いを見ているので、より高速な解決策はまったく別のものであることに言及したいと思いました。

したがって、あなたがしているのは内積であるためnumpy.dot、外部ライブラリ(LAPACK?)からの乗算と合計で構築された を使用します(便宜上test1、@Timの答えにもかかわらず、 の構文を使用します。余分な引数を渡す必要はありません。)

def test3(self):
    return np.dot(self.x, self.x)

またはおそらくさらに高速です(そして確かにより一般的です):

def test4(self):
    return np.einsum('i,i->', self.x, self.x)

ここにいくつかのテストがあります:

In [363]: paste
class Tester():
    def __init__(self, n):
        self.x = np.arange(n)
    def test1(self):
        return np.sum(self.x * self.x)
    def test2(self, x):
        return np.sum(x*x)
    def test3(self):
        return np.dot(self.x, self.x)
    def test4(self):
        return np.einsum('i,i->', self.x, self.x)
## -- End pasted text --

In [364]: t = Tester(10000)

In [365]: np.allclose(t.test1(), [t.test2(t.x), t.test3(), t.test4()])
Out[365]: True

In [366]: timeit t.test1()
10000 loops, best of 3: 37.4 µs per loop

In [367]: timeit t.test2(t.x)
10000 loops, best of 3: 37.4 µs per loop

In [368]: timeit t.test3()
100000 loops, best of 3: 15.2 µs per loop

In [369]: timeit t.test4()
100000 loops, best of 3: 16.5 µs per loop

In [370]: t = Tester(10)

In [371]: timeit t.test1()
100000 loops, best of 3: 16.6 µs per loop

In [372]: timeit t.test2(t.x)
100000 loops, best of 3: 16.5 µs per loop

In [373]: timeit t.test3()
100000 loops, best of 3: 3.14 µs per loop

In [374]: timeit t.test4()
100000 loops, best of 3: 6.26 µs per loop

小さな、ほぼ構文上の速度の違いについて言えば、スタンドアロン関数ではなくメソッドを使用することを考えてください。

def test1b(self):
    return (self.x*self.x).sum()

与えます:

In [385]: t = Tester(10000)

In [386]: timeit t.test1()
10000 loops, best of 3: 40.6 µs per loop

In [387]: timeit t.test1b()
10000 loops, best of 3: 37.3 µs per loop

In [388]: t = Tester(3)

In [389]: timeit t.test1()
100000 loops, best of 3: 16.6 µs per loop

In [390]: timeit t.test1b()
100000 loops, best of 3: 14.2 µs per loop
于 2013-11-04T23:45:15.377 に答える