虚拟机中怎么可以直接运行python 热度碾压Java、C#、C 的Python,为什么速度那么慢?

[更新]
·
·
分类:互联网
2065 阅读

热度碾压Java、C#、C

热度碾压Java、C#、C 的Python,为什么速度那么慢?

的Python,为什么速度那么慢?

先说结论:Python是一门动态类型的解释语言,且有全局解释器锁,这三点的底层实现导致了Python比Java、C 慢。
背景知识01001000 00000001 11000011
计算机CPU只能接受上面这样的01二进制语言,0和1用来控制高低电位。这样的0个代码被称为机器码。
C、C 等编译型语言依靠编译器将源代码转化为机器码后才能运行,Python、Java等解释型语言使用解释器将源代码翻译后在虚拟机上执行。对于Python,由于解释器的存在,其执行效率比C语言慢几倍甚至几十倍。
上图展示各个语言在不同任务上的速度。C语言经过几十年的发展,优化已经达到了极致。以C语言为基准,大多数解释语言,如Python、R会慢十倍甚至一百倍。Julia这个解释语言是个“奇葩”,因为它采用了JIT编译技术。
解决Python执行效率低的问题,一种解决办法是使用C/C 语言重写Python函数,但是这要求程序员对C/C 语言熟悉,且调试速度慢,不适合绝大多数Python程序员。另外一种非常方便快捷的解决办法就是使用Just-In-Time(JIT)技术。
Python是一种解释语言Python是一门解释语言,Python为我们提供了基于硬件和操作系统的一个虚拟机,并使用解释器将源代码转化为虚拟机可执行的字节码。字节码在虚拟机上执行,得到结果。
我们使用python 来执行一份源代码时,Python解释器会在后台启动一个字节码编译器(Bytecode Compiler),将源代码转换为字节码,这个过程被称为编译阶段。字节码是一种只能运行在虚拟机上的文件,Python的字节码默认后缀为.pyc,Python生成.pyc后一般放在内存中继续使用,并不是每次都将.pyc文件保存到磁盘上。有时候我们会看到自己Python代码文件夹里有很多.pyc文件与.py文件同名,但也有很多时候看不到.pyc文件。pyc字节码通过Python虚拟机与硬件交互。虚拟机的出现导致程序和硬件之间增加了中间层,运行效率大打折扣。相信使用过虚拟机软件的朋友深有体会,在原生的系统上安装一个虚拟机软件,在虚拟机上再运行一个其他系统,经常感觉速度下降,体验变差,这与Python虚拟机导致程序运行慢是一个原理。
Just-In-Time(JIT)技术为解释语言提供了一种优化,它能克服上述效率问题,极大提升代码执行速度,同时保留Python语言的易用性。使用JIT技术时,JIT编译器将Python源代码编译成机器直接可以执行的机器语言,并可以直接在CPU等硬件上运行。这样就跳过了原来的虚拟机,执行速度几乎与用C语言编程速度并无二致。
Python是动态类型的原生Python速度慢的另一个重要原因是变量类型不确定,即动态类型。Python声明一个变量的语法很简单,如a 1,但没有指定a到底是一个整数和一个浮点小数,甚至还可以把a赋值为一个字符串。C 和Java中,变量都是有类型的,比如在C 中,声明一个整数。
int a 1计算机在执行代码时,必须知道是什么类型的,才能给这个变量分配合适的内存,调用相应的指令。Python解释器要进行大量的类型推断,推断出一个变量是什么类型,转换成计算机可执行的机器码,这个过程会非常耗时。这个推断的过程发生在将.py文件换换成
.pyc
字节码的编译阶段。
与Python不同,C/C 等编译型语言要提前把整个程序先编译好,再执行可执行文件。而且只需要编译一次,后面再使用这个程序时就不需要编译了。
Python编译和运行都慢一个程序的运行时间一般是编译时间加运行时间。
总时间 编译时间 运行时间Python动态类型的特点导致编译时间较长,基于解释器的特点导致其运行时间较长,加起来导致总时间比C 和Java慢。
因此,Python非常容易上手,极大方便了开发人员,相应地,给程序员节省下来的时间就丢给了Python解释器,导致Python执行程序的非常慢。
Python 全局解释器锁其实Python只是一种计算机语言,计算机语言可以有不同的解释器,我们常用的Python一般是CPython这个解释器实现。CPython有全局解释器锁(GIL),这个锁限制了Python使用多核CPU的并行处理能力。关于多核CPU如何工作,可以参见我的头条文章:
突破这个锁并不难,可以使用Python提供的multiprocessing库来使用多核。
总结Python是一门动态类型的解释语言,且有全局解释器锁,这三点的底层实现导致了Python比Java、C 慢。

在java中,GraalVM是jvm的未来吗?

强答一下。结论是GraalVM想成为一统天下的“最终”虚拟机。
大部分脚本语言或者有动态特效的语言都需要一个语言虚拟机运行,比如CPython,Lua,Erlang,Java,Ruby,R,JS,PHP,Perl,APL等等,但是这些语言的虚拟机水平,对,就是具体的实现,差距很大,比如CPython的VM就不忍直视,JVM的HotSpotVM,C#的CLR和JS的v8却是state of the art级别,那么能不能付出较小努力,用一个state of the art的虚拟机,来运行这些语言,让它们享受该虚拟机的一些工匠特性,比如gc,锁,jit等?
答案基本上是肯定的。首先,对于Java,Scala,Groovy这些本来就是JVM-based的语言,那没有什么压力,直接上JVM即可。对于CPython,R,Ruby,PHP乃至自己写的一门新的语言,回顾一下我们的一般做法:首先解析源代码到AST,然后写一个AST解释器-gt当有些人用这个语言的时候,语言设计者可能继续迭代,实现一个虚拟机,包括GC,运行时等,代码执行仍然是AST解释器-gt用的人多了,继续迭代,将AST转换为字节码,使用字节码解释器-gt用的人特别多,性能也很关键,如果这个语言社区有足够资金和人力,那么可以写JIT编译器,提升GC性能等,大部分语言都到不了这一步。我们希望一门语言在AST解释器节点性能就足够好了,不用花那么多精力和财力做性能优化等,这就是Truffle语言框架的动机,Truffle是一个Java框架,自然跑在JVM上,在这个框架下,用户只需要实现具体语言的AST解释器,付出的努力比较小,性能也足够好。

理想很丰满,现实很骨感
Graa|VM刚出来是很多热度,可惜鉴于O厂的名生在外,社区反应冷漠
这玩意就像J院老板和大家说,我家姑娘年青飘亮N子大,大家不要娶媳妇了,努力挣钱都给我家姑娘吧!
现在大家也都偿偿鲜搞一下,很少社区主力推