为什么JavaScript中的单态和多态问题? [英] Why do monomorphic and polymorphic matter in JavaScript?

查看:110
本文介绍了为什么JavaScript中的单态和多态问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读一些关于变化检测的文章,他们都说单态函数比多态性快得多。例如,这里是一个引用:

I've been reading some articles on change detection, and all of them say that monomorphic functions are much faster than polymorphic. For example, here is a quote:


(..)原因是,它必须以动态方式编写,所以
它可以检查每个组件,无论它的模型结构看起来像
。虚拟机不喜欢这种动态代码,因为它们不能优化它。它被认为是多态的,因为对象的形状
并不总是相同的。 Angular在
运行时为每个组件创建变化检测器类,这些类是单态的,因为它们知道
正是组件模型的形状。虚拟机可以完美地优化这些代码,这使得它的执行速度非常快。好的
的事情是我们不必过多关心,因为
Angular自动完成。(..)

(..)The reason for that is, that it has to be written in a dynamic way, so it can check every component no matter what its model structure looks like. VMs don’t like this sort of dynamic code, because they can’t optimize it. It’s considered polymorphic as the shape of the objects isn’t always the same. Angular creates change detector classes at runtime for each component, which are monomorphic, because they know exactly what the shape of the component’s model is. VMs can perfectly optimize this code, which makes it very fast to execute. The good thing is that we don’t have to care about that too much, because Angular does it automatically.(..)

来源

现在,我试图找到monomoprhic vs polymorphic的例子,但无法在任何地方找到它。任何人都可以解释差异,为什么它会更快?

Now, I was trying to find examples of monomoprhic vs polymorphic, but couldn't find it anywhere. Could anyone care to explain the difference, and why is it faster?

推荐答案

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

The answer lies in the fact that VMs can do heuristic detection of "hot functions", meaning code that is executed hundreds or even thousands of times. If a function's execution count exceeds a predetermined limit, the VMs optimizer might pick up that bit of code and attempt to compile an optimized version based on the arguments passed to the function. In this case, it presumes your function will always be called with the same type of arguments (not necessarily the same objects).

这个原因在中有详细记载。 v8特定指南文档,其中解释了整数与一般数字优化。假设你有:

The reason for this is well-documented in this v8-specific guideline document where an integer vs. general number optimization is explained. Say you have:

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

...并且你总是用整数调用这个函数,这个方法可能会被优化编译一个在CPU上执行整数求和的函数,这很快。如果在优化之后你给它一个非整数值,那么VM会优化该函数并回退到未优化的版本,因为它不能对非整数执行整数求和,并且该函数会返回错误的结果。

...and you're always calling this function with integers, this method might be optimized by compiling a function that does integer summation on the CPU, which is fast. If after optimization you feed it a non-integer value, then the VM deoptimizes the function and falls back to the unoptimized version, since it cannot perform integer summation on non-integers and the function would return erroneous results.

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

In languages where you specify overloaded monomorphic methods you can get around this problem by simply compiling multiple versions of the same method name with different argument signatures which are then optimized on their own. This means that you call different optimized methods because using differenty typed arguments requires you to use a different overloaded method, so there's no question of which method you're using.

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

You might think that you could keep multiple copies of optimized functions in the VM and check types to determine which optimized compiled function to use. In theory, that would work, if type checking before method invocation were free or very inexpensive. In practice, that usually doesn't turn out to be the case, and you'd probably want to balance things against real-world code to determine the best tradeoff threshold.

这是一个更普遍的解释v8的优化编译器(来自Google I / O 2012):

Here's a more generalized explanation v8's optimizing compiler in particular (from Google I/O 2012):

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

简而言之:功能在JIT编译器中反复调用具有相同类型的相同类型,因此更快。

这篇关于为什么JavaScript中的单态和多态问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆