Python的运行加速:C究竟比python快在哪

最近在做Python语言运行的加速,python的加速过程绕不开Python与C/C++的交互问题,但方式各式各样。我先后接触了ctypes,pybind11,cython等各种方式,各有千秋,适用于不同场合。但cython的使用最能领略到C到底会比python快在哪。

用cython加速python的原因大致可以归结为两个:

  1. 将运行时解释变为提前编译;
  2. 将动态类型变为静态类型。

运行时解释与提前编译的差异

这一步的优化从网上搜集的资料和我实际的操作看,都是能够提高10%到30%的速度。

这其实跟我以往的认知有一定的差距。

之前的大部分时间里,我所从事的工作都是通过c语言来实现,对于大型项目来讲,编译本身耗时有时候是很可怕的。之前对于解释性语言一个简单的理解是,在运行过程中实现了编译,然后再运行。粗略的讲,这样的理解虽然不全面,但倒是不错。在这种粗略理解的基础上,再结合编译C语言时的耗时,就很理所当然的认为解释性语言运行慢的原因主要是由于运行时的解释造成的。

就目前的实际情况来看,这样的理解显然就行不通了。

一个相同逻辑的算法,如果是CPU密集型,并且都运行于单进程,用python实现的程序比用C实现的程序运行时间可能会差出两、三个数量级,绝不仅仅是看到的10%到30%的差距。

那么这个差距是如何造成的呢?

动态与静态类型的不同

这是另一个相当重要的原因。

作为一个对C语言比较熟悉的程序员在学习python的时候,你一定会遇到一系列让人很不习惯的地方,但有时又让人十分庆幸,因为这让编程变得异常简单。其中一定会有一条,你发现在python中不用指明变量的数据类型。一个在C中被严格限制,让你在写程序时犹豫不决,瞻前顾后,并且时不时引入一个段错误的游戏规则,在python中凭空消失了,这给我们带来了极大的便利,但这是有代价的。

也就是我们说的动态数据类型与静态数据类型的区别。这是拉低python运行速度的一个非常重要的原因。也让我们对python运行速率的优化有了很大的空间。

直观的来理解这种差别带来的速率变化:

在变量未被运行时,它可能是任何类型,只有当该数据被运行时,才会根据对它的赋值推断出它在此刻的数据类型。之后,这个变量又可以被赋值为其他类型,下一次对它的运行还需要再次对其类型进行推测。

而对于编译型语言来讲,每个变量在编译阶段就被确认好了具体的数据类型。这就直接跳过了python在运行时才去做的工作。

再来感性的说一说

比起python,C语言显然离计算机硬件“更近”一些,它对于计算机硬件的操控更加直接,编程者的逻辑能够更直接的映射给计算机硬件,从而计算机硬件能够以更加接近编程者的思路对结果进行运算。当然C和计算机硬件之间还隔着一层汇编。通过对C语言进行优化,让编译器翻译出的汇编能够以最简单的逻辑实现最终目,从而缩短运算时间,有时候甚至要耍点花招,欺骗编译器一下。当然这又是另一个层面上的优化了。

领略一下语言发展的趋势

从最早的通过穿孔纸带直接编写二进制机器语言,到汇编的发明和设计,从C语言等编译语言的发明,再到以python为代表的解释性语言的产生,虽然各式各样的语言被发明的时间有交叉重叠,甚至他们的归类也并非泾渭分明,但是从整体的趋势来讲,就是有这样一个产生的顺序。

也可以从被执行的角度来看一下:

python的官方解释器是Cpython,用C\C++语言实现,也就是在运行过程中首先会被解释为C语言的规则,然后C语言会被编译为运行计算机相应的汇编,再由汇编翻译为二进制码由计算机执行。

从一个开发者的角度,我们也可以直观的感觉到,功能的实现越来越便捷,而运行速度越来越慢。

总之,计算机语言发发展会离计算机越来越远,而距离人类的自然语言越来越近。我想,计算机语言一定会进化为自然语言的一个子集,而我们大概已经依稀的感觉到,AI可能会成为这种未来计算机语言的“解释器”或“编译器”。虽然在AI领域每种语言都被采用,而python显然由于其便捷性也展现出其独特的优势,而成为从更“低级一些”的语言到AI的一个衔接。最终计算机语言的完整谱系将会是什么样子,我们拭目以待。

你可能感兴趣的:(python,c语言,开发语言)