LoginSignup
3
3

More than 5 years have passed since last update.

nodejsで大量のEntityを生成するときには class や prototypeベースで作成する方がコストが低い

Last updated at Posted at 2015-12-15

はじめに

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 な書き方をしていたので、今後は気をつけよう、、と思いました。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3