首页 \ 问答 \ Python解释器可以优化哪些内容?(Which things can the Python interpreter optimize? [closed])

Python解释器可以优化哪些内容?(Which things can the Python interpreter optimize? [closed])

我认为由于懒惰的评估声明,如:

if True and True (...):
    # do something

...应该在True and解释器后面的True and part之后跳过。 但是,与编译代码相比,我认为Python解释器不能像显式布尔比较那样优化坏样式 ,对吧?

if condition == True:
    # do something

编译器会对此进行优化并删除== True部分,但是解释器总是必须评估在condition ==部分之后等待哪些语句,从而在每次执行代码时进行不必要的== True比较?!

是否存在更多这样的陷阱,解释器无法优化代码? 我知道这最后一个问题是相当开放的,但我想一些流行的例子确实存在?


I think due to lazy evaluation statements like:

if True and True (...):
    # do something

...should be skipped right after the True and part by the Python interpreter. However, in contrast to compiled Code, I think the Python interpreter can not optimize bad style like explicit boolean comparisions, right?

if condition == True:
    # do something

A compiler would optimize this and delete the == True part, but the interpreter always has to evaluate which statements wait after the condition == part, thus doing the unnecessary comparison of == True every time the code is executed?!

Do more of such pitfalls exist, where the interpreter can not optimize code? I know this last question is quite open, but I guess some popular examples do exist?


原文:https://stackoverflow.com/questions/38755305
更新时间:2020-03-26 14:48

最满意答案

编译本身并不多(CPython编译为字节码),但语言极其动态的特性阻碍了“传统”优化,这些优化由不变量引导,这些不变量在Python编译时难以检查,因为语言的语义这样,关于代码实际应该做什么的大多数信息仅在运行时可用。

你的if condition == True:示例是一个好的:只有当编译器可以证明condition总是一个布尔值时才能优化比较,如果它是从当前范围内的文字派生的,那么这是一个非平凡的任务 -如果它可以证明,在运行时,没有人设法用其他东西覆盖True (仅在Python 2 IIRC中可能)。

请注意,某些类型的推断是可能的,而实际上,像Jedi这样的代码完成工具是如何工作的; 然而,Jedi可以采取一些捷径并假设某种标准环境,而解释器必须应对语言允许的全局变量的最奇怪的修改。

所以,总的来说CPython并没有非常努力地优化任何东西 - 实际上,它似乎没有进行任何类型的“智能”代码分析,AFAICT它们大多试图建立一个高效但“大多是香草”的解释器。 因此,期望几乎完全按照您所写的内容付费,没有优化器来保存草率代码。

顺便说一句,你的例子并不是解释器完成的优化,而是操作符的语义是如何定义的(并且指定它and / or做短路评估并且它不是可选的“优化”非常重要) ,因为如果右手操作数有副作用,它可能会改变程序的可观察行为)。

对于动态而不是跟踪JIT的语言更好的方法 - 解释器允许代码运行一段时间,并观察看起来保持良好的不变量(例如, condition似乎总是一个布尔值, True始终是True ,某些变量总是一个整数,...),然后使用此信息编译代码的优化版本的机器代码。 只要上面的不变量确实存在,就可以运行 - 但只要用于编译优化版本的其中一个前提被破坏,执行就会返回解释模式,并再次开始跟踪以查明是否有新的优化版本可以建造。

因此,典型情况很好地应用了通常的优化技术,但每当发生奇怪的事情(但语言允许)时,运行时可以回退到常规的“文字”字节码解释。

这是用于从大多数动态语言中挤出良好性能的方法(大多数现代JavaScript引擎使用这种基本方法的一些变体),并且在PyPy中使用Python。


It's not much compilation per se (CPython does compile to bytecode), but the extremely dynamic nature of the language hampers "traditional" optimizations, which are guided by invariants which are difficult to check at compile time in Python, because the semantics of the language is such that most information about what the code is actually supposed to do is only available at runtime.

Your if condition == True: example is a good one: that comparison could be optimized only if the compiler could prove that condition is always a boolean, which is a non-trivial task if it derives from anything but literals in the current scope - and if it could prove that, at runtime, nobody managed to overwrite True with something else (possible only in Python 2 IIRC).

Mind you, some type inference is possible, and it's actually how code completion tools like Jedi work; however, Jedi can take some shortcuts and assume e.g. some kind of standard environment, while the interpreter has to cope with the most bizarre modifications to the globals that the language do allow.

So, in general CPython does not try very hard to optimize anything - actually, it doesn't seem to do any kind of "smart" code analysis, AFAICT they mostly try to build an efficient but "mostly vanilla" interpreter. So, expect to pay almost exactly for what you write, there's no optimizer to save sloppy code.

By the way, your and example is not an optimization done by the interpreter, it's just how the semantic of the operator is defined (and it's quite crucial that it's specified that and and or do short circuit evaluation and it's not an optional "optimization", since it could alter the observable behavior of the program if the right hand operand had side effects).

A better approach for a language that dynamic is instead that of a tracing JIT - the interpreter lets the code run for a while, and observes the invariants that seem to hold well (for example, condition seems to always be a boolean, True is always True, some variable is always an integer, ...), and then uses this information to compile to machine code an optimized version of the code. This is let run as long as the invariants above do hold - but as soon as one of the premises used to compile the optimized version is broken, the execution goes back into interpreted mode, and tracing begins again to find out if a new optimized version can be built.

Thus, the typical case is optimized well, applying the usual optimization techniques, but whenever something bizarre (but allowed by the language) happens, the runtime can fallback to the regular "literal" bytecode interpretation.

This is the approach used to squeeze good performance from most dynamic languages (most modern JavaScript engines use some variation of this basic approach), and in Python is used in PyPy.

2016-08-04

相关文章

更多

最新问答

更多
  • css在元素之前中断列而不破坏包装器(css break column before element without breaking the wrapper)
  • 如何在Xamarin共享项目中使用自定义渲染器(How to use Custom Renderer in Xamarin Shared Project)
  • 如何为特定表中的特定字段设置唯一?(How to set unique for specific field from specific table?)
  • Google SDK iOS - sign()方法完成处理程序(Google SDK iOS - sign() method completion handler)
  • 在具有接口{}值的地图上实现String()(Implement String() on a map with interface{} values)
  • 检查数据库中是否已存在用户名(Check if username already exist in DB)
  • 使用javascript进行ajax调用时阻止用户交互(Block user interaction while doing ajax call using javascript)
  • 什么'if(err)'在Javascript中精确测试?(What does 'if (err)' tests precisely in Javascript?)
  • jQuery mouseleave无法正常工作(jQuery mouseleave not working)
  • 寻求使用的一些说明(Seeking some clarification on use of )
  • 将数组传递给注释的语法(syntax for passing array to annotation)
  • 用于从两个日期范围之间的文件中提取数据的Shell脚本(Shell script to extract data from file between two date ranges)
  • 元素隐藏但父()没有(Element hides but parent() not)
  • 如何使用Google App Engine Java平台开发web ui(How to develop web ui with Google App Engine Java platform)
  • 对于OWL A级;(For an OWL class A; Getting all properties that A is their domain)
  • Excel VBA公式格式问题(Excel VBA Formula Format Issue)
  • ORA - 02287序列号不允许在这里(ORA - 02287 sequence number not allowed here)
  • Github拉忽略特定文件(Github Pull Ignore Specific File)
  • SQL CONVERT函数在SQL Server中工作但不在应用程序中(SQL CONVERT function working in SQL Server but not in application)
  • backbone.js适用于大型应用程序(backbone.js for large applications)
  • 防止程序关闭(Preventing program from closing)
  • 生成不带图像的heightMap(Generating a heightMap without an Image)
  • Bootstrap - 如何将包含文本的div居中?(Bootstrap - How to center div that has text inside it?)
  • Android - 片段findViewById()总是null?(Android - Fragment findViewById() always null?)
  • 确定CSS中的高度(Figuring out heights in CSS)
  • 使用__autoload包含类和使用命名空间(Use __autoload to include class and use namespace)
  • setTimeout()不允许我传递文本值[重复](setTimeout() doesn't allow me to pass text values [duplicate])
  • 在NSUserDefault中恢复值(Restoring value in NSUserDefault)
  • 知道如何将这种下沉的悬停效果添加到图像/链接吗?(Any idea how to add this sinking hover effect to an image/link?)
  • 在XIB中淡入/淡出UISegmentedControl(fade in/fade out UISegmentedControl in XIB)