時間を節約し、オブジェクトを変更済みとしてマークしたいので、クラスを作成してその__setattr__
関数をオーバーライドしました。
import time
class CacheObject(object):
__slots__ = ('modified', 'lastAccess')
def __init__(self):
object.__setattr__(self,'modified',False)
object.__setattr__(self,'lastAccess',time.time())
def setModified(self):
object.__setattr__(self,'modified',True)
object.__setattr__(self,'lastAccess',time.time())
def resetTime(self):
object.__setattr__(self,'lastAccess',time.time())
def __setattr__(self,name,value):
if (not hasattr(self,name)) or object.__getattribute__(self,name)!=value:
object.__setattr__(self,name,value)
self.setModified()
class example(CacheObject):
__slots__ = ('abc',)
def __init__(self,i):
self.abc = i
super(example,self).__init__()
t = time.time()
f = example(0)
for i in range(100000):
f.abc = i
print(time.time()-t)
処理時間を計測したところ、2秒かかりました。オーバーライドされた関数をコメントアウトしたところ、処理時間は 0.1 秒でした。オーバーライドされた関数の方が遅いことはわかっていますが、ギャップが 20 倍近く大きすぎます。私は何か間違っているに違いないと思います。
cfiからの提案を取る
1.if条件を削除する
def __setattr__(self,name,value):
# if (not hasattr(self,name)) or object.__getattribute__(self,name)!=value:
object.__setattr__(self,name,value)
self.setModified()
実行時間が 1.9 に短縮されました。少し改善されましたが、変更されていないオブジェクトを変更済みとしてマークすると、他のプロセスでより多くのコストがかかるため、オプションではありません。
2.self.funcをclassname.func(self)に変更
def __setattr__(self,name,value):
if (not hasattr(self,name)) or object.__getattribute__(self,name)!=value:
object.__setattr__(self,name,value)
CacheObject.setModified(self)
実行時間は 2.0 です。実際には何も変わっていません。
3) setmodified 関数の抽出
def __setattr__(self,name,value):
if (not hasattr(self,name)) or object.__getattribute__(self,name)!=value:
object.__setattr__(self,name,value)
object.__setattr__(self,'modified',True)
object.__setattr__(self,'lastAccess',time.time())
実行時間が 1.2 になりました!!これは素晴らしいことです。コストはまだ高いですが、ほぼ 50% の時間を節約できます。