我知道这可能是一个非常明显的答案,而且我将自己暴露在无用的尖刻评论中,但我不知道答案,所以就这样吧。
如果 Python 在运行时编译为字节码,是否只是初始编译步骤需要更长的时间?如果是这种情况,那不只是代码中的一小部分前期成本(即,如果代码运行了很长时间,C 和 python 之间的差异会缩小吗?)
我知道这可能是一个非常明显的答案,而且我将自己暴露在无用的尖刻评论中,但我不知道答案,所以就这样吧。
如果 Python 在运行时编译为字节码,是否只是初始编译步骤需要更长的时间?如果是这种情况,那不只是代码中的一小部分前期成本(即,如果代码运行了很长时间,C 和 python 之间的差异会缩小吗?)
解释 Python 代码并使其变慢的不仅仅是事实,尽管这肯定会限制您获得的速度。
如果以字节码为中心的观点是正确的,那么要使 Python 代码与 C 代码一样快,您所要做的就是用直接调用函数替换解释器循环,消除任何字节码,然后编译生成的代码。但它不是那样工作的。您也不必相信我的话:您可以自己测试它。Cython 将 Python 代码转换为 C,但是转换然后编译的典型 Python 函数不会显示 C 级速度。您所要做的就是查看一些因此生成的典型 C 代码以了解原因。
真正的挑战是多重分派(或任何正确的术语——我不能直截了当),我的意思是这样一个事实,即a+b
ifa
和b
都被称为整数或浮点数可以编译成一个操作C,在 Python 中,你必须做更多的计算a+b
(获取名称绑定到的对象,通过__add__
等等)
这就是为什么要使 Cython 达到 C 速度,您必须在关键路径中指定类型;这就是 Shedskin 如何使用(笛卡尔积)类型推断快速使 Python 代码摆脱 C++ 的方式;以及 PyPy 的速度如何——JIT 可以关注代码的行为方式并专注于类型之类的事情。每种方法都消除了动态性,无论是在编译时还是在运行时,这样它就可以生成知道自己在做什么的代码。
字节码对 CPU 来说不是自然的,因此它们需要解释(通过称为解释器的 CPU 本地代码)。字节码的优势在于它可以进行优化、预计算并节省空间。C 编译器生成机器代码,机器代码不需要解释,它是 CPU 原生的。