请帮助:) - 我必须检查访问属性的性能 - 工厂函数,连接继承和类,我不明白为什么连接继承失败?毕竟,对Concatenative继承中复制的属性的访问应该是最快的。 我在Chrome和Safari上运行测试,CI总是丢失。 https://jsperf.com/factory-function-vs-concatenative-inheritance-get
此测试的代码:
const alien = {
sayHello () {
return `Hello, my name is ${ this.name }`;
}
};
//Delegate prototype
const createAlienFF = (name) => {
return Object.assign(Object.create(alien), {
name
});
}
//Delegate prototype - creating objects
var tabFF = [];
for(var i = 0; i < 1000; i++ ) {
tabFF[i] = createAlienFF('Clark' + i);
}
//Concatenative inheritance
const createAlienCI = (name) => {
return Object.assign(
{},
alien,
{name: name}
);
}
//Concatenative inheritance - creating objects
var tabCI = [];
for(var i = 0; i < 1000; i++ ) {
tabCI[i] = createAlienCI("Clark" + i );
}
//Class
class Alien {
constructor(name) {
this.name = name
}
sayHello() {
return `Hello, my name is ${ this.name }`;
}
}
//Class - creating objects
var tabClass = [];
for(var i = 0; i < 1000; i++ ) {
tabClass[i] = new Alien("Clark" + i );
}
//Tests
//1 - Delegate prototype
for(var i = 0; i < 1000; i++ ) {
tabFF[i].sayHello();
}
//2 - Concatenative inheritance
for(var i = 0; i < 1000; i++ ) {
tabCI[i].sayHello();
}
//3 - Class
for(var i = 0; i < 1000; i++ ) {
tabClass[i].sayHello();
}
答案 0 :(得分:1)
毕竟,访问Concatenative继承中复制的属性应该是最快的。
你为什么这么认为?因为它是一个直接的属性访问,不需要遍历原型链?
嗯,这可能是关于天真引擎实施的一个很好的推理。但是你没有考虑专门针对继承而定制的对象模型的优化,使得(类)实例上的方法访问速度极快。请查看https://github.com/v8/v8/wiki/Design%20Elements#fast-property-access,https://blog.ghaiklor.com/optimizations-tricks-in-v8-d284b6c8b183,http://richardartoul.github.io/jekyll/update/2015/04/26/hidden-classes.html和伟大的http://mrale.ph/blog/2012/06/03/explaining-js-vms-in-js-inline-caches.html。要点:V8优化了对“已知形状”对象的方法访问,即在您的情况下继承自alien
或Alien.prototype
的对象(它们共享相同的隐藏类 )。它知道猜测在你的循环中,只使用那个形状的对象,并且可以推断它们都调用完全相同的sayHello
函数。这是从中获取代码的恒定位置,甚至可以进行进一步的优化,例如内联。另一方面,createAlienCI
工厂创建的对象也都共享相同的形状,但每个对象都包含其单独的sayHello
属性。所有这些属性可能包含相同的函数对象,但我们无法知道(我们不会猜测它 - 这是一个不寻常的模式)。因此,引擎每次调用它之前都会从每个实例中获取函数引用 - 至少它知道每个实例中的哪个(在哪个内存偏移处)看起来因为它们的形状不变。