Python(和其他动态语言)的哪些语义特征导致其缓慢?
没有。
语言实现的性能是金钱,资源和博士学位论文的功能,而不是语言功能。Self比Smalltalk更具动态性,比Python,Ruby,ECMAScript或Lua更具动态性,并且它的VM优于所有现有的Lisp和Smalltalk VM(实际上,Self发行版附带了一个用Self编写的小型Smalltalk解释器,甚至比大多数现有的Smalltalk VM还要快),并且与当时的C ++实现竞争,有时甚至更快。
然后,Sun停止了对Self的资助,IBM,微软,英特尔和Co.开始对C ++进行资助,这种趋势反过来了。Self开发人员离开Sun创立了自己的公司,在那里他们使用为Self VM开发的技术来构建有史以来最快的Smalltalk VM(Animorphic VM),然后Sun购回了该公司,并对其进行了稍微修改。 Smalltalk VM现在以“ HotSpot JVM”的名称而闻名。具有讽刺意味的是,Java程序员视动态语言为“慢”,而事实上,Java在采用动态语言技术之前一直很慢。(是的,没错:HotSpot JVM本质上是Smalltalk VM。字节码验证程序会进行很多类型检查,但是一旦字节码被验证程序接受,VM尤其是优化程序和JIT实际上就不会做对静态类型非常感兴趣!)
CPython并没有做很多使动态语言(或动态调度)快速化的工作:动态编译(JIT),动态优化,投机内联,自适应优化,动态反优化,动态类型反馈/推断。还有一个问题,就是几乎所有的核心和标准库都是用C编写的,这意味着即使您突然将Python的速度提高了100倍,也无济于事,因为大约95%的代码由A执行Python程序是C,而不是Python。如果所有内容都是用Python编写的,那么即使是适度的加速也会产生雪崩效应,算法会变得更快,核心数据结构也会变得更快,但是当然,核心数据结构也将在算法中使用,核心算法和核心数据也将被使用。结构用于其他地方,
在当今的系统中,有几件事对内存管理的OO语言(无论动态还是非动态)都是不利的。虚拟内存和内存保护可以成为特别是垃圾回收性能以及整个系统性能的杀手。而且,使用内存安全的语言完全没有必要:为什么在没有使用该语言的任何内存访问的情况下,防止非法的内存访问?Azul已经发现可以使用现代功能强大的MMU(Intel Nehalem和更新的版本,以及与AMD相当的MMU)来帮助进行垃圾回收,而不是阻碍垃圾回收,但是即使CPU支持它,主流操作系统的当前内存子系统也不够强大。允许这个(这就是为什么Azul的JVM实际运行在裸金属虚拟化之外 操作系统,而不是其中)。
在Singularity OS项目中,Microsoft测量了在使用MMU保护而不是类型系统进行进程分离时对系统性能的影响约30%。
Azul在构建专用Java CPU时注意到的另一件事是,现代主流CPU在尝试降低缓存丢失的成本时将重点放在完全错误的事情上:他们尝试通过分支预测,内存预取,等等。但是,在高度多态的OO程序中,访问模式基本上是伪随机的,根本没有什么可预测的。因此,所有这些晶体管都被浪费掉了,而应该做的是减少每个缓存丢失的成本。(总成本是#misses *成本,主流试图降低第一个,而Azul则是第二个。)Azul的Java Compute Accelerators可能有20000个并发的高速缓存未命中,并且仍在取得进展。
Azul刚开始时,他们认为他们会采用一些现成的I / O组件并设计自己的专用CPU内核,但实际上最终需要做的恰恰相反:他们采用了相当标准的机架3地址RISC内核,并设计了自己的内存控制器,MMU和缓存子系统。
tl; dr:Python的“慢”不是该语言的属性,而是a)它的幼稚(主要)实现,以及b)现代CPU和OS专为使C快速运行而设计的事实,以及它们的功能C语言的使用要么没有帮助(缓存),要么甚至是在损害(虚拟内存)Python性能。
而且,您可以在这里插入几乎任何具有动态即席多态性的内存管理语言…当谈到有效实现的挑战时,甚至Python和Java几乎都是“同一种语言”。