Python是一种动态语言。这意味着您在编写代码方面有很大的自由度。由于python公开了大量的自省(顺便说一句,这非常有用),许多优化根本无法执行。例如,在第一个示例中,python无法知道调用它时list是什么数据类型。我可以创建一个非常奇怪的类:class CrazyList(object):
def append(self, value):
def new_append(value):
print "Hello world"
self.append = new_append
显然这是没有用的,但是我可以写这个,它是有效的python。如果我将这个类型传递给上面的函数,代码将与您“缓存”append函数的版本不同。在
我们可以为+=写一个类似的例子(如果“编译器”优化了它,它可能会产生一些副作用,而这些副作用是不会被执行的)。在
为了有效地优化,python必须知道你的类型。。。对于绝大多数代码,它没有(傻瓜证明)的方法来获取类型数据,所以它甚至不尝试大多数优化。在
请注意,这是一个微优化(和well documented一个)。它在某些情况下是有用的,但在大多数情况下,如果您编写惯用的python,则没有必要使用它。e、 g.您的list示例最好使用.extend方法编写,如您在帖子中所述。大多数情况下,如果你有一个足够紧的循环,使得某个方法的查找时间在你的整个程序运行时很重要,那么要么你应该找到一种方法来重写这个循环以提高效率,要么甚至把计算推到一种更快的语言中(例如C)。有些库在这方面非常擅长(numpy)。在
也就是说,有一些优化可以由“编译器”在称为“窥视孔优化器”的阶段安全地完成。e、 g.它将为您做一些简单的恒定折叠:
^{pr2}$
在某些情况下,它会缓存值以备以后使用,或将一种类型的对象转换为另一种类型的对象:>>> def translate_tuple(a):
... return a in [1, 3]
...
>>> import dis
>>> dis.dis(translate_tuple)
2 0 LOAD_FAST 0 (a)
3 LOAD_CONST 3 ((1, 3))
6 COMPARE_OP 6 (in)
9 RETURN_VALUE
(注意,列表被转换成tuple,并缓存在python3.2+set文本也可以转换成frozenset并进行缓存)。在