我在一个类中的艰难的循环中使用numpy.random.normal
函数。在
class MyClass(MyBaseClass):
def run(self):
while True:
...
self.L.append(numpy.random.normal(0,1))
我知道在Python中使用多个查找非常慢。在numpy.random.normal
中有3个查找:首先查找numpy
,然后是random
,然后是{
所以我决定通过将numpy.random.normal
分配给一个局部变量_normal
来解决这个问题。在
开始吧:
^{pr2}$我真正关心的是描述词。当访问一个类中的一个变量时,所有基类都会查找同名的数据描述符。描述如下here:
Check
objectname.__class__.__dict__
for attrname. If it exists and is a data-descriptor, return the descriptor result. Search all bases ofobjectname.__class__
for the same case.
所以,我想,如果我像上面那样把_normal
放在局部空间中,它将查找数据描述符的所有基类。我担心它会成为经济放缓的根源。在
我的担心有道理吗?在
我应该担心在基类中查找描述符所需的时间吗?在
在类中使用某个函数时,有没有更好的方法来加速对位于模块深处的函数的访问?在
在对答案的评论中进行了讨论。在
我决定提供一些似乎很重要的执行细节(对于我的特殊情况)。在
实际上,代码更接近于此(非常简化):
class MyClass(MyBaseClass):
def __iter__(self):
return self
def next(self):
self.L.append(numpy.random.normal(0,1))
def run(self):
while True:
self.next()
如果你必须这样做(函数查找实际上是主要的成本吗?随机数生成并不便宜)您应该意识到一个全局+一个attr查找(
MyClass._normal
)并不比一个全局+三个attr查找(numpy.random.normal
)便宜多少。您真正想要的是在循环中获得zero全局或attr查找,这只能通过在函数内定义_normal
来实现。如果您真的很想缩短周期,还应该预先绑定list append调用:对比反汇编输出(仅用于
^{pr2}$append
语句):与
更好的方法是向量化生成许多随机法线偏离,并一次性将它们附加到列表中,可以使用
size
参数对numpy.random.normal
执行此操作。在那要看情况了。对于你想要的应用程序,它已经足够快了吗?如果是这样,不要担心。CPython、PyPy、NumPy和moore定律的变化可能会在“减速”成为一个症结之前缓解它的严重程度。在
相关问题 更多 >
编程相关推荐