为什么口译语言会变慢?

Nat*_*pos 30 performance interpreted-language

我正在阅读解释性语言的优缺点,其中一个最常见的缺点是速度慢,但为什么解释语言中的程序会变慢?

ang*_*son 58

本机程序使用为其运行的处理器编写的指令运行.

解释语言就是"解释".一些其他形式的指令由运行时读取和解释,运行时又执行本机机器指令.

这样想吧.如果您可以用您的母语与某人交谈,那通常比让翻译人员将您的语言翻译成其他语言以便听众理解更快.

请注意,我上面描述的是在语言在解释器中运行时.有许多语言的解释器,还有用于构建本机机器指令的本机链接器.速度降低(但可能的大小)仅适用于解释的上下文.

因此,说语言很慢,而不是它运行的上下文很慢,这有点不正确.

C#不是一种解释语言,即使它使用了一种中间语言(IL),这在执行之前就被JIT打成原生指令,所以它有一些相同的速度降低,但不是全部,但我敢打赌如果你为C#或C++构建了一个完全成熟的解释器,它也会运行得更慢.

而且要明确的是,当我说"慢"时,这当然是一个相对的术语.


Lot*_*har 18

所有答案似乎都错过了这里真正重要的一点.这是详细说明"解释"代码的实现方式.

解释的脚本语言较慢,因为它们的方法,对象和全局变量空间模型是动态的.在我看来,这是脚本语言的真正定义,而不是它被解释的事实.这需要在每次访问变量或方法调用时进行许多额外的哈希表查找.它的主要原因是它们在多线程和使用GIL(全局解释器锁)时都很糟糕.这种查找是花费大部分时间的地方.这是一个痛苦的随机内存查找,当你得到L1/L2缓存未命中时会非常痛苦.

谷歌的Javascript Core8速度非常快,几乎可以通过C速度进行简单的优化:它们将对象数据模型固定下来并创建内部代码来访问它,就像本机编译程序的数据结构一样.添加或删除新变量或方法时,将丢弃并重新编译整个编译代码.

该技术在Deutsch/Schiffman的论文"Smalltalk-80系统的有效实现"中得到了很好的解释.

php,python和ruby没有这样做的问题很简单:这项技术实现起来非常复杂.

只有谷歌有钱支付JavaScript,因为基于浏览器的快速JavaScript解释器是他们十亿美元商业模式的基本需求.


Dig*_*oss 8

将interpeter视为您不具备的机器的模拟器

简短的答案是,编译语言是由机器指令执行,而解释那些由程序(写在编译语言)执行读取源或字节码,然后基本上是模仿了一个假想的机器已经运行程序直接如果机器存在.

将解释的运行时视为一台机器的模拟器,此时您实际上并未碰巧使用它.

Java,C#和其他人使用的JIT(Just In Time)编译器显然很复杂.从理论上讲,它们与"AOT"("一次性")编译器一样好,但在实践中,这些语言运行速度较慢,并且需要让编译器在程序运行时使用内存和时间.但是,如果你说在这里的任何一个准备好吸引狂热的JIT防守者,他们坚持认为JIT和AOT之间没有理论上的区别.如果你问他们Java和C#是否和C和C++一样快,那么他们就会开始找借口并稍稍冷静下来.:-)

因此,C++完全适用于可以始终使用最大可用计算量的游戏.

在桌面和Web上,面向信息的任务通常由具有更多抽象或至少更少编译的语言完成,因为计算机速度非常快且问题不是计算密集型的,所以我们可以花一些时间在目标上,比如时间到市场,程序员生产力,可靠的内存安全环境,动态模块化和其他强大的工具.


csc*_*hol 7

这是一个很好的问题,但在我看来应该有所不同,例如:"为什么解释语言比编译语言慢?"

我认为解释性语言本身很慢是一种常见的误解.解释语言并不慢,但是,根据用例,可能比编译版本.在大多数情况下,解释语言实际上足够快!

"足够快",加上使用像Python这样的语言的生产力提高,例如,C应该足以考虑解释性语言.此外,如果您真的需要速度,您可以使用快速C实现替换解释程序的某些部分.但话说回来,首先测量并确定速度是否真的是问题,然后进行优化.


gbn*_*gbn 5

循环 a 100 次,循环内容被解释 100 次为低级代码。

不缓存、不重用、不优化。

简单来说,编译器一次解释为低级代码

评论后编辑:

  • JIT 是编译代码,而不是解释代码。它只是稍后编译而不是预先编译
  • 我指的是经典定义,而不是现代实际实现

  • 一旦您将 JIT 引入其中,我认为您就不能将其称为解释语言 - 至少不是*纯*解释语言。 (5认同)

Gre*_*reg 5

除了其他答案之外还有优化:当你编译一个程序时,你通常不关心编译需要多长时间 - 编译器有很多时间来优化你的代码。当您解释代码时,它必须非常快地完成,因此可能无法进行一些更聪明的优化。