7

今日、オフィスでいくつかのコードを調べたところ、次のコードが見つかりました。それは私に衝撃を与えました。

class XXXX():
    def __init__(self, k, v):
        for i in range(len(k)):
            setattr(self, k[i], v[i])

すると、ほとんどのクラスが同じように書かれていることがわかりました。これは、すべてのクラスが同じクラスであることを意味し、唯一の違いはそれらの名前です。

このプロジェクトsetattr()では、属性の設定に使用さgetattr()れ、属性の取得に使用されます。プロファイル ログsetattrでは、2700 回getattr呼び出され、3800 回呼び出されました。かかった時間は、それぞれ 0.003 秒と 0.005 秒でした (全プロセス: 0.069 秒)。

私は考えて速度を落としていますが、すべてのコードsetattrgetattr書き直せば速度が向上するかどうかはわかりません。

obj.attribute = value は よりも速く実行されますsetattr(obj,'attribute',value)か?

4

2 に答える 2

3

はい、少なくとも CPU レベルでは、はるかに低速ですgetattrsetattr

はオブジェクトごとに 1 回しか呼び出されないため__init__、非常に多くのオブジェクトを作成しない限り、私はそれについて心配する必要はありません。

オブジェクトの属性が何度もアクセスされる場合は、それらのセクションを書き直す価値があります。ただし、最初に注意深いプロファイリングを行う必要があります。

于 2012-10-11T19:21:06.590 に答える
2

私は小さなテストをしました。約2倍遅くなりました。

Increment using member took 2.8221039772

Increment using attr took 5.94811701775

これが私のコードです

import timeit
class Dummy(object):
    __slots__ = ['testVal']
    def __init__(self):
        self.testVal = 0

    def increment_using_attr(self):
        i = getattr(self, 'testVal')
        setattr(self, 'testVal', i+1)

    def increment(self):
        self.testVal += 1

if __name__ == '__main__':
    d = Dummy()
    print "Increment using member took {0}".format(timeit.Timer(d.increment).timeit(10000000))
    print "Increment using attr took {0}".format(timeit.Timer(d.increment_using_attr).timeit(10000000))

Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz のマシンで実行

于 2016-12-13T19:47:04.960 に答える