javascript - 深度继承链是否会减慢 V8 JavaScript 引擎中的方法查找速度?

标签 javascript inheritance v8 mixins

我正在用 TypeScript 为游戏编写基类。它具有发送消息、资源管理等功能。 灵感来自 Mixins ,我写了下面的代码(编译成 JavaScript):

function Messenger(Base) {
    return class Messenger extends Base {
        $dispatch(e) {
           // TODO
        }
    };
}
function ResourceManager(Base) {
    return class ResourceManager extends Base {
        $loadRes(key) {
            // TODO
            return Promise.resolve({});
        }
    };
}
class Component {
}
class GameBase extends Component {
    start() {
        console.log('start');
    }
    init() {
        console.log('init');
    }
}
const Klass = ResourceManager(Messenger(GameBase));
var gg = new Klass();
gg.start();

据我所知,当我尝试调用 gg.start 时,JavaScript 引擎会查找原型(prototype)链,在这种情况下它会稍微长一些,并且当 mixins 时它会变成事件长生长: method lookup

这会减慢方法查找的速度吗? V8 是否优化了这个查找过程,我可以忽略查找开销吗?

最佳答案

这里是 V8 开发人员。这是一个复杂的问题;简短的回答是“视情况而定”。

在进行查找时必须遍历更长的原型(prototype)链会花费更多时间,这毫无疑问是正确的。但是,如果仅执行一次或两次,那么该时间通常太短而无足轻重。

所以下一个问题是:执行此类查找的频率是多少? V8 会尽可能地缓存查找结果(如果您想了解更多信息,请搜索术语“内联缓存”);与所有缓存一样,此类缓存的有效性关键取决于看到的不同案例的数量。

因此,如果您的代码大部分是“单态的”(即在任何给定的 foo.bar 查找中,foo 将始终具有相同的类型/形状,包括相同的原型(prototype)链) 或低度多态(最多四种不同类型的 foo),那么完整的原型(prototype)链遍历只需要完成一次(或分别最多四次),然后将使用缓存的结果,因此如果您执行此类代码数千次,您将看不到一步或数百步长的原型(prototype)链之间的性能差异。

另一方面,如果您的属性加载或存储可以看到许多不同的类型(在某些框架中往往会发生这种情况,其中每次查找都经过一些中央 getProperty(object, property) {/* do一些框架的东西,然后: */return object[property]; function),然后缓存就没用了,V8 每次都必须执行完整的查找。这对于较长的原型(prototype)链来说特别慢,但这意味着它总是比可缓存的情况慢得多(即使是较短的原型(prototype)链)。

总而言之,如果您对整体程序设计比较谨慎并避免在相同的代码位置有许多不同的类型,那么您可以轻松地承受很长的原型(prototype)链。事实上,尽可能多地保持代码的单态类型往往比保持原型(prototype)链长度短有更大的影响。另一方面,较短的原型(prototype)链长度确实让引擎的生命周期更轻松,而且我个人认为它们可以(如果你不过分)也提高了可读性,所以其他条件相同,我建议您尽可能保持对象模型简单。

关于javascript - 深度继承链是否会减慢 V8 JavaScript 引擎中的方法查找速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56559270/

相关文章:

javascript - 使用 javascript [NO jQuery] 获取 div

java - jackson 忽略外部库中父类(super class)的所有属性

java - 从父类返回子类

c# - 在 C# 中覆盖静态类

eclipse - Eclipse 中的 node.js - 大多数人使用哪些插件?

node.js - 发布大型 NPM 包

javascript - 在 Ember.js 中计算日期差异

javascript - 如何检查浏览器是否在 MAC 上运行?

javascript - 确定去优化的原因

javascript - 多选mysql Node js