Mar*_*aio 48 javascript performance function-prototypes
我在这里阅读(Douglas Crockford)使用原型运算符向Javascript类添加方法也保存了内存.
然后我读到了John Resig的文章 "用一堆原型属性实例化一个函数是非常非常快的 ",但他是在谈论以标准方式使用原型,还是他在他的文章中谈论他的具体例子?
例如,正在创建此对象:
function Class1()
{
this.showMsg = function(string) { alert(string); }
}
var c = new Class1();
c.showMsg();
Run Code Online (Sandbox Code Playgroud)
比创建这个对象慢吗?
function Class1() {}
Class1.prototype.showMsg = function(string) { alert(string); }
var c = new Class1();
c.showMsg();
Run Code Online (Sandbox Code Playgroud)
PS
我知道原型用于创建继承和单例对象等.但是这个问题与这些主题没有任何关系.
编辑:对于JS对象和JS静态对象之间的性能比较它可能感兴趣的人可以阅读下面的答案.静态对象肯定更快,显然只有在不需要多个对象实例时才能使用它们.
And*_*rew 60
这是一个有趣的问题,所以我运行了一些非常简单的测试(我应该重新启动我的浏览器以清除内存,但我没有;为了它的价值而拿这个).它看起来至少在Safari和Firefox上prototype运行速度明显更快[编辑:如前所述,不是20倍].我确信使用功能齐全的对象进行真实测试将是一个更好的比较.我运行的代码就是这个(我分别运行了几次测试):
var X,Y, x,y, i, intNow;
X = function() {};
X.prototype.message = function(s) { var mymessage = s + "";}
X.prototype.addition = function(i,j) { return (i *2 + j * 2) / 2; }
Y = function() {
this.message = function(s) { var mymessage = s + "";}
this.addition = function(i,j) { return (i *2 + j * 2) / 2; }
};
intNow = (new Date()).getTime();
for (i = 0; i < 1000000; i++) {
y = new Y();
y.message('hi');
y.addition(i,2)
}
console.log((new Date()).getTime() - intNow); //FF=5206ms; Safari=1554
intNow = (new Date()).getTime();
for (i = 0; i < 1000000; i++) {
x = new X();
x.message('hi');
x.addition(i,2)
}
console.log((new Date()).getTime() - intNow);//FF=3894ms;Safari=606
Run Code Online (Sandbox Code Playgroud)
这是一个真正的耻辱,因为我真的很讨厌使用prototype.我喜欢我的目标代码是自封装的,不允许漂移.我想当速度很重要时,我没有选择.该死.
[编辑]非常感谢@Kevin,他指出我以前的代码是错误的,大大提高了报告的prototype方法速度.固定后,原型仍然明显加快,但差异并不大.
shm*_*613 32
我猜这取决于你想要创建的对象的类型.我和安德鲁进行了类似的测试,但是使用静态对象,静态对象赢了.这是测试:
var X,Y,Z,x,y,z;
X = function() {};
X.prototype.message = function(s) { var mymessage = s + "";}
X.prototype.addition = function(i,j) { return (i *2 + j * 2) / 2; }
Y = function() {
this.message = function(s) { var mymessage = s + "";}
this.addition = function(i,j) { return (i *2 + j * 2) / 2; }
};
Z = {
message: function(s) { var mymessage = s + "";}
,addition: function(i,j) { return (i *2 + j * 2) / 2; }
}
function TestPerformance()
{
var closureStartDateTime = new Date();
for (var i = 0; i < 100000; i++)
{
y = new Y();
y.message('hi');
y.addition(i,2);
}
var closureEndDateTime = new Date();
var prototypeStartDateTime = new Date();
for (var i = 0; i < 100000; i++)
{
x = new X();
x.message('hi');
x.addition(i,2);
}
var prototypeEndDateTime = new Date();
var staticObjectStartDateTime = new Date();
for (var i = 0; i < 100000; i++)
{
z = Z; // obviously you don't really need this
z.message('hi');
z.addition(i,2);
}
var staticObjectEndDateTime = new Date();
var closureTime = closureEndDateTime.getTime() - closureStartDateTime.getTime();
var prototypeTime = prototypeEndDateTime.getTime() - prototypeStartDateTime.getTime();
var staticTime = staticObjectEndDateTime.getTime() - staticObjectStartDateTime.getTime();
console.log("Closure time: " + closureTime + ", prototype time: " + prototypeTime + ", static object time: " + staticTime);
}
TestPerformance();
Run Code Online (Sandbox Code Playgroud)
此测试是对我在以下位置找到的代码的修改:
结果:
IE6:关闭时间:1062,原型时间:766,静态对象时间:406
IE8:关闭时间:781,原型时间:406,静态对象时间:188
FF:关闭时间:233,原型时间:141,静态物体时间:94
Safari:关闭时间:152,原型时间:12,静态对象时间:6
Chrome:关闭时间:13,原型时间:8,静态对象时间:3
吸取的教训是,如果你不要有一个需要从同一个类实例化许多不同的对象,然后创建它作为一个静态对象手中夺了下来.所以仔细想想你真正需要什么样的课程.
小智 6
所以我决定也测试一下.我测试了创建时间,执行时间和内存使用情况.我使用Nodejs v0.8.12和在Mac Book Pro上运行的mocha测试框架启动到Windows 7."快速"结果使用原型,"慢"结果使用模块模式.我创建了100万种每种类型的对象,然后在每个对象中访问了4种方法.结果如下:
c:\ABoxAbove>mocha test/test_andrew.js
Fast Allocation took:170 msec
·Fast Access took:826 msec
state[0] = First0
Free Memory:5006495744
·Slow Allocation took:999 msec
·Slow Access took:599 msec
state[0] = First0
Free Memory:4639649792
Mem diff:358248k
Mem overhead per obj:366.845952bytes
? 4 tests complete (2.6 seconds)
Run Code Online (Sandbox Code Playgroud)
代码如下:
var assert = require("assert"), os = require('os');
function Fast (){}
Fast.prototype = {
state:"",
getState:function (){return this.state;},
setState:function (_state){this.state = _state;},
name:"",
getName:function (){return this.name;},
setName:function (_name){this.name = _name;}
};
function Slow (){
var state, name;
return{
getState:function (){return this.state;},
setState:function (_state){this.state = _state;},
getName:function (){return this.name;},
setName:function (_name){this.name = _name;}
};
}
describe('test supposed fast prototype', function(){
var count = 1000000, i, objs = [count], state = "First", name="Test";
var ts, diff, mem;
it ('should allocate a bunch of objects quickly', function (done){
ts = Date.now ();
for (i = 0; i < count; ++i){objs[i] = new Fast ();}
diff = Date.now () - ts;
console.log ("Fast Allocation took:%d msec", diff);
done ();
});
it ('should access a bunch of objects quickly', function (done){
ts = Date.now ();
for (i = 0; i < count; ++i){
objs[i].setState (state + i);
assert (objs[i].getState () === state + i, "States should be equal");
objs[i].setName (name + i);
assert (objs[i].getName () === name + i, "Names should be equal");
}
diff = Date.now() - ts;
console.log ("Fast Access took:%d msec", diff);
console.log ("state[0] = " + objs[0].getState ());
mem = os.freemem();
console.log ("Free Memory:" + mem + "\n");
done ();
});
it ('should allocate a bunch of objects slowly', function (done){
ts = Date.now ();
for (i = 0; i < count; ++i){objs[i] = Slow ();}
diff = Date.now() - ts;
console.log ("Slow Allocation took:%d msec", diff);
done ();
});
it ('should access a bunch of objects slowly', function (done){
ts = Date.now ();
for (i = 0; i < count; ++i){
objs[i].setState (state + i);
assert (objs[i].getState () === state + i, "States should be equal");
objs[i].setName (name + i);
assert (objs[i].getName () === name + i, "Names should be equal");
}
diff = Date.now() - ts;
console.log ("Slow Access took:%d msec", diff);
console.log ("state[0] = " + objs[0].getState ());
var mem2 = os.freemem();
console.log ("Free Memory:" + mem2 + "\n");
console.log ("Mem diff:" + (mem - mem2) / 1024 + "k");
console.log ("Mem overhead per obj:" + (mem - mem2) / count + 'bytes');
done ();
});
});
Run Code Online (Sandbox Code Playgroud)
结论:这支持了本文中其他人发现的内容.如果您经常创建对象,那么原型机制显然更快.如果您的代码花费大部分时间访问对象,那么模块模式会更快.如果您对内存使用很敏感,那么原型机制每个对象使用约360个字节.
| 归档时间: |
|
| 查看次数: |
19281 次 |
| 最近记录: |