読者です 読者をやめる 読者になる 読者になる

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 万回なので一つ一つはたいしたことないのだけど、塵も積もれば。