はじめに
Javascriptで、単純な値やFunctionをもつEntityを作成する場合、いくつか書き方があると思います。
下記 検証スクリプトのEntityFunction
のような書き方は、「Objectが生成される度に関数スコープが作られるので遅い」と聞いたので検証してみました。結論として全くそのとおりでした。
version
- nodejs: v4.2.1
- babel-core: 6.1.2
検証
下記のように
-
EntityClass
のようにES6 の class を使う- 今回は babelでES5に変換しているので、そうでない場合にどうかはまた別ですが
-
EntityFunction
のような書き方 -
EntityFunction2
のような書き方
で、10万回Objectを生成して、それぞれMethodを呼んでみた時間を測りました。
検証スクリプト
bench.js
require('babel-core/register');
require('./bench.es6');
bench.es6
class EntityClass {
constructor(name, age, prop) {
this.name = name;
this.age = age;
this.prop = prop;
}
getName() {
return this.name;
}
getProp() {
return this.prop;
}
getHoge() {
return this.prop.hoge + this.age;
}
}
const EntityFunction = function(name, age, prop) {
const self = {};
self.getName = () => name;
self.getProp = () => prop;
self.getHoge = () => prop.hoge + age;
return self;
};
// 関数スコープを毎回作らない、関数だけを使っている書き方
const EntityFunction2 = function(name, age, prop) {
const self = {};
self.name = name;
self.age = age;
self.prop = prop;
self.getName = getName;
self.getProp = getProp;
self.getHoge = getHoge;
return self;
};
function getName() { return this.name }
function getProp() { return this.prop }
function getHoge() { return this.prop.hoge + this.age }
function bench(name, proc) {
const startTime = new Date();
proc();
const endTime = new Date();
console.log(`${name}: ${endTime - startTime} ms`);
}
const loopNum = 100000;
bench('EntityClass', function() {
let entity;
for (let i=0; i<loopNum; i++) {
entity = new EntityClass('name', 100, {hoge: 100});
[entity.getName(), entity.getName(), entity.getHoge()];
}
// console.log([entity.getName(), entity.getName(), entity.getHoge()]);
});
bench('EntityFunction', function() {
let entity;
for (let i=0; i<loopNum; i++) {
entity = EntityFunction('name', 100, {hoge: 100});
[entity.getName(), entity.getName(), entity.getHoge()];
}
// console.log([entity.getName(), entity.getName(), entity.getHoge()]);
});
bench('EntityFunction2', function() {
let entity;
for (let i=0; i<loopNum; i++) {
entity = EntityFunction2('name', 100, {hoge: 100});
[entity.getName(), entity.getName(), entity.getHoge()];
}
// console.log([entity.getName(), entity.getName(), entity.getHoge()]);
});
検証結果
% node bench.js
EntityClass: 7 ms
EntityFunction: 642 ms
EntityFunction2: 30 ms
差は歴然でした。class的な書き方の方が無駄な関数スコープが作られないからか速いんですね。
まあ、10万回生成実行した時のコストですので、100回くらいなら効率悪い書き方でも1msくらいですね。
さいごに
私は結構 EntityFunction
な書き方をしていたので、今後は気をつけよう、、と思いました。