据我所知,导入模块时,该文件会被编译成.pyc
文件以使其更快?为什么主文件也没有编译成.pyc
?这会减慢速度吗?保持主文件尽可能小是不是更好,或者无关紧要?
答案 0 :(得分:31)
加载模块时,py文件被“字节编译”为pyc文件。时间戳记录在pyc文件中。 这样做不是为了让它运行得更快,而是加载更快。 因此,在加载模块时“字节编译”模块是有意义的。
[编辑:包括备注,参考]
从PEP 3147开始“字节代码 汇编“:
CPython将其源代码编译为“字节代码”,出于性能原因, 只要源文件发生更改,它就会在文件系统上缓存此字节代码。 这使得Python模块的加载速度更快,因为编译阶段 可以被绕过。当您的源文件是foo.py时,CPython会缓存该字节 源代码旁边的foo.pyc文件中的代码。
字节码编译文件的方式如何 跟踪Python版本 和“py”文件更改:
它还在编译的字节代码“.pyc”文件中插入幻数。 每当Python更改字节代码格式时,这都会发生变化,通常是在主要版本中 这可确保为早期版本的VM构建的pyc文件不会导致问题。 时间戳用于确保pyc文件与py文件匹配 用来创造它。当幻数或时间戳不匹配时, py文件被重新编译并写入一个新的pyc文件。
“pyc”文件在Python主要版本中不兼容。当Python找到一个pyc时 文件具有不匹配的幻数,它会回落到较慢的进程中 重新编译源代码。
这就是原因,如果您只是分发为同一平台编译的“.pyc”文件将无法再工作,如果python版本发生变化。
在果壳中
如果有一个字节编译文件“.pyc”并且它的时间戳表明它是最近的那么它将被加载其他明智的python将回退加载“.py”文件的较慢方法。 “.py”文件的执行性能不受影响,但“.pyc”文件的加载速度比“.py”文件快。
考虑执行导入b.py
的a.py.Typical total performance = loading time (A.py) + execution time (A.py) +
loading time (B.py) + execution time (B.py)
Since loading time (B.pyc) < loading time (B.py)
You should see a better performance by using the byte compiled "pyc" files.
也就是说,如果你有一个大的脚本文件X.py,将其模块化并将内容移动到其他模块会导致利用字节码编译文件的较低加载时间。
另一个推论是模块往往比脚本或主文件更稳定。因此它根本不是字节编译的。
参考
答案 1 :(得分:0)
编译主脚本对于例如脚本来说会很烦人。 /usr/bin
。 .pyc文件在同一目录中生成,从而污染公共位置。