【发布时间】:2012-10-23 03:05:09
【问题描述】:
我想节省时间并将对象标记为已修改,因此我编写了一个类并覆盖其__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)提取集合修改函数
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% 的时间,尽管成本仍然很高。
【问题讨论】:
-
感谢您的数字反馈!我们可以争辩说涉及两个函数调用,并且由于删除一个将开销减少了 50%,因此您可能会被剩余的开销所困扰。但也许其他人有更多的想法。
标签: performance python-3.x double-underscore