basyura's blog

あしたになったらほんきだす。

prototype を使う場合と使わない場合の速度比較

prototype を知らずに作って今に至る某システム。レスポンス問題が再燃したので prototype の使用有無でどれだけ違うのかちょっと比較してみた。
簡単なオブジェクトを new で生成する場合の速度比較

  1. this.xxx を使ってグローバルな関数をメンバ(オブジェクトの外部からアクセスできる関数)として定義する
  2. this.xxx を使って内部関数をメンバとして定義する
  3. prototype を使って一つずつ関数を定義する
  4. prototype を使って一度に関数を定義する

1. this.xxx を使ってグローバルな関数をメンバ(オブジェクトの外部からアクセスできる関数)として定義する

var count = 100000
var start = new Date();
function Test1(a , b , c , d , e ) {
  this.a = a;
  this.b = b;
  this.c = c;
  this.d = d;
  this.e = e;

  this.m1 = p_m11;
  this.m2 = p_m12;
  this.m3 = p_m13;
  this.m4 = p_m14;
  this.m5 = p_m15;
}
function p_m11() {
  return this.a;
}
function p_m12() {
  return this.b;
}
function p_m13() {
  return this.c
}
function p_m14() {
  return this.d
}
function p_m15() {
  return this.e
}

for(var i = 0 ; i < count ; i ++) {
  var test = new Test1('a' , 'b' , 'c' , 'd' , 'e')
}

print(new Date().getTime() - start.getTime())

2. this.xxx を使って内部関数をメンバとして定義する

var count = 100000
var start = new Date();

function Test2(a , b , c , d , e ) {
  this.a = a;
  this.b = b;
  this.c = c;
  this.d = d;
  this.e = e;

  this.m1 = p_m21;
  this.m2 = p_m22;
  this.m3 = p_m23;
  this.m4 = p_m24;
  this.m5 = p_m25;

  function p_m21() {
    return this.a;
  }
  function p_m22() {
    return this.b;
  }
  function p_m23() {
    return this.c;
  }
  function p_m24() {
    return this.d;
  }
  function p_m25() {
    return this.e;
  }
}

for(var i = 0 ; i < count ; i ++) {
  var test = new Test2('a' , 'b' , 'c' , 'd' , 'e')
}

print(new Date().getTime() - start.getTime())

3. prototype を使って一つずつ関数を定義する

var count = 100000
var start = new Date();

function Test3(a , b , c , d , e ) {
  this.a = a;
  this.b = b;
  this.c = c;
  this.d = d;
  this.e = e;
}

Test3.prototype.m1 = function() {
  return this.a;
}
Test3.prototype.m2 = function() {
  return this.b;
}
Test3.prototype.m3 = function() {
  return this.c;
}
Test3.prototype.m4 = function() {
  return this.d;
}
Test3.prototype.m5 = function() {
  return this.e;
}

for(var i = 0 ; i < count ; i ++) {
  var test = new Test3('a' , 'b' , 'c' , 'd' , 'e')
}

print(new Date().getTime() - start.getTime())

4. prototype を使って一度に関数を定義する

var count = 100000
var start = new Date();

function Test4(a , b , c , d , e ) {
  this.a = a;
  this.b = b;
  this.c = c;
  this.d = d;
  this.e = e;
}

Test4.prototype = {
  m1 : function() {
    return this.a;
  },
  m2 : function() {
    return this.b;
  },
  m3 : function() {
    return this.c;
  },
  m4 : function() {
    return this.d;
  },
  m5 : function() {
    return this.e;
  }
}

for(var i = 0 ; i < count ; i ++) {
  var test = new Test4('a' , 'b' , 'c' , 'd' , 'e')
}

print(new Date().getTime() - start.getTime())

まとめ

  1. 506 [ms]
  2. 860 [ms]
  3. 315 [ms]
  4. 322 [ms]

prototype を使うと new した場合に関数群(?)が使いまわされるのでメモリ効率がいいってのは知ってたけど、速度も2倍近く違う。
対象が単純なオブジェクトだし実行回数も 10 万回なので一つ一つはたいしたことないのだけど、塵も積もれば。