Python可以优化这个简单的变量调用吗?

时间:2013-09-24 15:07:09

标签: python python-2.6

似乎python(2.6)无法优化这个简单的临时变量'a'?

我用来为某些代码分配一个局部变量,以减少行长度。

对我来说,这是一个简单的优化,任何正确的编译器都可以自动完成。

from dis import dis

def f(func):
  func()

def functioncall():
  print ' => function called'

def unoptimized():
  print 'in unoptimized'
  a = functioncall
  f(func=a)

def optimized():
  print 'in optimized'
  f(func=functioncall)

unoptimized()
optimized()

print 'dis(unoptimized)'
dis(unoptimized)
print 'dis(optimized)'
dis(optimized)

输出:

in unoptimized
 => function called
in optimized
 => function called
dis(unoptimized)
 10           0 LOAD_CONST               1 ('in unoptimized')
              3 PRINT_ITEM
              4 PRINT_NEWLINE

 11           5 LOAD_GLOBAL              0 (functioncall)
              8 STORE_FAST               0 (a)

 12          11 LOAD_GLOBAL              1 (f)
             14 LOAD_CONST               2 ('func')
             17 LOAD_FAST                0 (a)
             20 CALL_FUNCTION          256
             23 POP_TOP
             24 LOAD_CONST               0 (None)
             27 RETURN_VALUE
dis(optimized)
 15           0 LOAD_CONST               1 ('in optimized')
              3 PRINT_ITEM
              4 PRINT_NEWLINE

 16           5 LOAD_GLOBAL              0 (f)
              8 LOAD_CONST               2 ('func')
             11 LOAD_GLOBAL              1 (functioncall)
             14 CALL_FUNCTION          256
             17 POP_TOP
             18 LOAD_CONST               0 (None)
             21 RETURN_VALUE

为什么它无法自动删除?

 11           5 LOAD_GLOBAL              0 (functioncall)
              8 STORE_FAST               0 (a)

4 个答案:

答案 0 :(得分:5)

CPython是Python的标准实现,没有做太多优化;它是源代码到字节码的非常简单的翻译。抛出了一些优化(消除或提升if __debug__下的代码之一)并且我确实认为有某种窥视孔优化器,但我认为编译阶段的速度相当快,排除了进行大量分析。

可维护性似乎也是核心Python开发人员的关键。这里是a thread from 2009,其中考虑了删除死代码的补丁,然后被拒绝,因为它会使编译器的可维护性降低。

如果你想要高性能,你需要的不是CPython;也许PyPy会有所帮助。 Python通常经过优化以节省程序员时间,而不是运行时。如果您不想在字节码中使用死代码,请不要将其放在源代码中。 : - )

答案 1 :(得分:1)

原则上,Python解释器可以对此进行优化。

在实践中,人们使用Python编程,因为在其中编写代码的速度很快,而不是因为使用它编写的代码很快。所以在这种特殊情况下,程序员应该进行优化。

答案 2 :(得分:0)

在python中,你的源代码并没有完全消失 - def语句是一个可执行语句,用于创建一个函数对象。你在问为什么python不会巧妙地做一些事情,而不是优化名称中的问题。

如果需要,借助于棉绒工具,这种优化很容易手工完成。引入可能产生的意外后果并不值得。毕竟,python的重点是易于阅读和编写。

答案 3 :(得分:0)

TL; DR:这是一个功能。

我认为这种类型的优化默认情况下 ,因为y=g(f(x)) 等同于{{1这里有Python的副作用。

本地命名空间旨在在Python本身中访问:它们具有明确定义的API。 a=f(x) ; y=g(a)函数和eval语句(Python> = 2.4)的文档声明“如果提供,则locals可以是任何映射对象”。

一个可能的应用是在Python中编写Python调试器。我可以继承exec,以便本地命名空间中的每个读/写触发一些GUI事件;我现在能够在dicta之间观察到中间结果a=f(x)。没有这种可能性,我将不得不检查CPython虚拟堆栈,或者在任何其他Python实现中使用它们。

除了调试之外,我还看到了此功能的其他可能用途。我可以想象在视频游戏引擎中嵌入Python。负责故事,任务,角色,事件以及所有这些事情的设计师将他们的想象力转化为游戏内容,而不是编写代码。为了让他们的生活更轻松,我可以使用特殊的本地命名空间运行他们的脚本,该命名空间带有一些预加载和/或实时值。 名称y=g(a)my_hp将始终返回/设置触发脚本的“攻击”事件中涉及的两个生物的当前生命点数。我的设计师不需要一直输入their_hp(他们甚至不知道类和对象)。在某种程度上,self.将表现为全局或描述符,除了它对于生物来说是本地的,并且不需要显式的类/实例去引用。实现这种方式比尝试解析脚本更容易,并猜测我们何时必须在内容之前添加my_hp

简而言之:您永远不知道虚拟机将对您的代码执行什么操作,因此可能看起来相同的内容并非总是如此。