关于绩效:口译语言:越高越快?

Interpreted languages: The higher-level the faster?

到目前为止,我已经为他们设计了5种实验语言和口译员,作为一种爱好和娱乐。

我注意到的一件事是:类程序集语言只包含子例程和条件跳转作为结构,比高级语言if、while等的速度慢得多。我同时开发了它们,而且它们都是解释语言。我用C++编写了解释器,我试图尽可能快地优化代码执行部分。

我的假设是:在几乎所有情况下,解释语言的表现都会随着其水平(高/低)而上升。

  • 我基本上是对的吗?(如果没有,为什么?)

编辑:我甚至一次都没有提到这里编译的单词,它是关于解释还是解释!


在这两种情况下,都是插入代码。我可以想象,在更高层次的语言中,实现相同任务的指令更少,因此您在解释指令上花费的时间更少,在做一些有用的事情上花费的时间也更多。


最后,无论我们讨论的是汇编语言还是下一个大事件语言(TNBL),解析您的语言中的一行文本都将花费大致相同的时间。从字面意义上讲,这不是真的,但从某种意义上说,在图灵式的大O符号中,这是真的。

如果(同样地,"大致")需要相同的时间来确定这意味着什么:

1
mov $3, $4, $5

如下所示:

1
print"foo"

…那么让我们想象一下用我们的两种语言写"你好世界"。汇编解释器将有一个更复杂的程序来解析。比如,n行长,是tnbl hello wolld的n倍。所以你最基本的开销是N倍长。

除此之外,您还拥有以更简单的语言执行的所有代码,这些语言模拟寄存器、操作等的行为。这是一项大量的工作。在tnbl中,解释代码的语义和您可以在宿主语言中做的事情之间几乎有一对一的映射。这意味着从语义到执行的开销大大减少。

我相信你会看到一些Java程序员会回避这篇论文,但我会指出Java有两个优点:一个中间字节码,它试图在执行代码之前尽可能地将代码接近硬件,而成千上万的人类年陷入开发时间和THA的运行时间优化。T语言。他们的语言很难与业余爱好者的语言保持一致。= ]


当然,现实比这要复杂一些。随着语言、解释程序和编译器变得更加复杂,机器出现了优化性能的新机会。此外,任何给定程序的性能在很大程度上取决于程序员编写的代码的质量。

此外,性能以不同的方式影响不同类型的程序。例如,业务线应用程序几乎总是以其速度命中率的大部分来查找数据库中的数据并将其发送到网上,而游戏程序员必须处理一个完全不同的性能概念,即视频卡帧速率。

所以性能图并不像看上去那么简单。


如果您有一个带有一个命令的解释语言:runMyEntireProgramNatively(),它将比带有更多命令的解释语言更快。每个命令执行的次数越少,解释所花费的时间与实际执行任务的时间之比就越大。


我想你大概是对的一半。如果你绘制了解释速度图,在x轴上有语言水平,在y轴上有执行速度,你会得到一条"浴缸"曲线——解释一种极低水平的语言可以非常快,解释一种极高水平的语言也可以非常快。在这两者之间,解释速度要慢得多。

对于一个非常高级的输入语言(例如,APL),您得到的解释开销最小,因为您可以在解析相对较少的输入代码的基础上做大量的工作。

在另一个极端,你可以得到相当不错的速度,因为有了足够低的水平语言,解释变得几乎微不足道。第四个实现的内部解释器就是一个主要的例子。这些通常表示一个给定的程序非常紧凑,这往往是相当缓存友好,所以至少在理论上,您可以获得与纯机器代码一样快的执行速度(甚至比纯机器代码更快)。

最初的意图是大多数JVM、.NET"托管"环境、Smalltalk字节代码解释器等都适合后一种情况。正如大多数试图开发这些的人很快发现的那样,很难将解释开销保持在足够低的水平来完成这一任务。我所知道的每一个适合这个类的内部循环都是用汇编语言手工编写的,通常是由一个好的汇编语言程序员编写的。我几乎可以这么说,如果你尝试使用一种更高级的语言(甚至是C语言),它将变得更慢,而且可能会显著地变慢(当你为每个输入指令增加开销时,即使在内部循环中有一个额外的指令,也几乎肯定会导致一个可测量的速度惩罚。TY)。


显然,这将取决于您如何实现不同的语言。

我猜想需要更多的指令被解释来在较低层次的解释语言中做同样的事情,而且与较低层次的语句相比,必须解释每一个低层次的指令将产生开销。


假设两者都是以相同的方式实现的,低级语言没有被优化,高级语言没有扩展到低级中间代码-"可能"。

在这种情况下,高级语言的优点是每一条指令都可以填充更多编译(更快)的代码。

但在实践中,低级别的解释语言应该能够减少每条指令的开销,并且通常更容易用实现JIT编译。每一个实现的好坏最终将决定它们是如何相互叠加的。

我会说实现一种更快的高级语言更容易。(以我有限的经验)


你如何做一个公平的比较?

我假设您不计算解析速度,我假设您正在生成一个中间字节代码指令集,这就是您要解释的。

假设您有一个"基准",它是一个循环,用于对数组的元素求和。如果您的高级语言对此有特殊的字节码指令,那么在高级语言中,要解释的字节码更少,这就解释了为什么它更快。


总结:标杆很难。你不能从轶事中概括。

这不是证据支持的规则。

你是如何建立你的实验得出"更高=更快"的结论的?您是否有相同算法和测试集的示例实现,这些示例实现允许您客观地衡量一种解释语言与另一种解释语言之间的差异?

如果您只是创建一个小型基准点,那么从太少的数据点得出结论的可能性非常高。

例如,如果一种解释语言有一个快速排序运算符,您可能会认为"啊哈!快一点!"而不是必须手工实现排序的语言。但是,quicksort具有最坏的情况O(n^2)性能。如果我给您的高级操作一个最坏情况数据集的例子,另一个手工实现的合并排序将击败它。