我读过一些有关变更检测的文章,所有文章都说单态函数比多态函数快得多。例如,这是一个引号:



Source

现在,我试图找到单晶与多晶的示例,但在任何地方都找不到。谁能解释这个差异,为什么会更快?

最佳答案

答案在于,虚拟机可以对“热功能”进行启发式检测,这意味着可以执行数百甚至数千次的代码。如果函数的执行计数超过预定限制,则VM优化器可能会选择该代码位,并尝试根据传递给函数的参数来编译优化版本。在这种情况下,假定您的函数将始终使用相同类型的参数(不一定是相同的对象)进行调用。

此原因在v8-specific guideline document中有充分的记录,其中解释了整数与一般数字优化。说您有:

function add(a, b) { return a + b; }

...而且您总是使用整数来调用此函数,此方法可能会通过编译一个在CPU上执行整数求和的函数来优化,此方法速度很快。如果在优化后将非整数值提供给它,则VM会对函数进行非优化,然后回退到未优化的版本,因为它无法对非整数执行整数求和,并且该函数将返回错误的结果。

在指定重载单态方法的语言中,可以通过简单地编译具有不同参数签名的相同方法名称的多个版本来解决此问题,然后对其进行单独优化。这意味着您将调用不同的优化方法,因为使用不同类型的参数要求您使用不同的重载方法,因此毫无疑问您正在使用哪种方法。

您可能认为您可以在VM中保留优化功能的多个副本,并检查类型以确定要使用哪个优化编译功能。从理论上讲,如果方法调用之前的类型检查是免费的或非常便宜的,那将是可行的。在实践中,通常情况并非如此,您可能需要在实际代码中进行权衡,以确定最佳折衷阈值。

以下是v8特别优化的编译器的更笼统的解释(来自Google I/O 2012):

https://youtu.be/UJPdhx5zTaw?t=26m26s

简而言之:在JIT编译器中优化了一遍又一遍用相同类型调用的函数。

10-04 19:13