谢邀。为什么Python很慢?由于各种原因,Python比Fortran和C慢:其中有一个很主要的原因是Python是动态类型而不是静态类型。
这意味着在程序执行时,解释器不知道定义的变量的类型。 此图表总结了C变量(我使用C作为编译语言的替代)和Python变量之间的区别:
cint vs pyint
对于C中的变量,编译器通过其定义知道类型。 对于Python中的变量,在程序执行时你所知道的只是它是某种Python对象。
因此,如果您在C中编写以下内容:
C编译器从一开始就知道a和b是整数:它们根本不可能是其他任何东西! 有了这些知识,它可以调用添加两个整数的例程,返回另一个整数,这只是内存中的一个简单值。 作为粗略的原理图,事件序列如下所示:
C加法将1分配给a
将2分配给b
调用binary_add (a,b)
将结果分配给c
Python中的等效代码如下所示:
这里解释器只知道1和2是对象,但不知道它们是什么类型的对象。因此,解释器必须检查每个变量的PyObject_HEAD以找到类型信息,然后为这两种类型调用适当的求和例程。最后,它必须创建并初始化一个新的Python对象来保存返回值。事件序列看起来大致如下:
Python加法将1分配给a
1A。将a-> PyObject_HEAD-> typecode设置为整数
1B。设置a-> val = 1
将2分配给b
2A。将b-> PyObject_HEAD-> typecode设置为整数
2B。设置b-> val = 2
调用binary_add(a,b)
3A。在a-> PyObject_HEAD中找到typecode
3B。 a是整数;值是a-> val
3C。在b-> PyObject_HEAD中找到typecode
3D。 b是整数;值是b-> val
3E。调用binary_add (a-> val,b-> val)
3F。结果是结果,并且是整数。
创建一个Python对象c
4A。将c-> PyObject_HEAD-> typecode设置为整数
4B。设置c-> val结果
所有动态类型都意味着任何操作都涉及更多步骤,这是Python与数值数据操作相比较慢的主要原因。