为什么getattr()比自己慢了很多.__ dict __。get()?

问题描述:

以下示例来自Python 2.7上的REST数据库驱动程序。为什么getattr()比自己慢了很多.__ dict __。get()?

在下面的__setattr__方法,如果我使用注释getattr()线,它降低了从600个RPS的对象实例化性能230

为什么getattr()比在这种情况下self.__dict__.get()这么慢得多?

class Element(object): 

    def __init__(self, client): 
     self._client = client 
     self._data = {} 
     self._initialized = True 

    def __setattr__(self, key, value): 
     #_initialized = getattr(self, "_initialized", False) 
     _initialized = self.__dict__.get("_initialized", False) 
     if key in self.__dict__ or _initialized is False: 
      # set the attribute normally 
      object.__setattr__(self, key, value) 
     else: 
      # set the attribute as a data property 
      self._data[key] = value 
+1

另一方面,如果你有这样的性能差异,请在本地变量中缓存'self .__ dict__' - 即使只有两次访问它。 ('__setattr__'开头的'dict_ = self .__ dict__') – jsbueno 2012-03-20 17:45:40

总之:因为getattr(foo,bar)does the same thing as foo.bar,这不是刚刚访问__dict__财产同样的事情(一开始,getattr必须选择合适的__dict__,但有很多更多的事情)。

详细信息包含在或关联到这里:http://docs.python.org/reference/datamodel.html(搜索“getattr”)。

+2

@bereal:你需要重新阅读东西。 foo .__ dict __。get()的必要操作是getattr()的一个真子集。 – bukzor 2012-03-20 17:12:50

+2

@bereal请记住,python字节码不对应于原始操作。你可以有非常少量的字节码来调用一个非常复杂的函数,而一个简单的表达式可以产生更多的字节码。另外,bukzor说的是正确和相关的。 – Marcin 2012-03-20 17:17:42

+0

@bereal这并不能证明'foo .__ dict__'与getattr(foo,'__dict __')'相同,因为可以调用'getattr(foo,'__ dict __')'来提高效率比取消引用任意属性。 – Marcin 2012-03-20 17:35:30