blog.kur.jp

バイオリンと山、自転車をこよなく愛するkurのチラシの裏。たまには技術的なことを書いたりするかも知れません。

JavaScriptで文字列を扱う際のデータ型とオブジェクトの処理速度

JavaScriptにおいて,文字列を扱う方法は下記の2つがあります.

  • 文字列型として扱う
  • Stringオブジェクトとして扱う

ソースコードのチューニングをしていて,どっちで処理するのが速いのか,ちょっと気になったので調べてみました.

結論から言うと,以下の実験行ってみたところ,現段階ではStringオブジェクトで扱ったほうが良さそうなのでした.

実験概要

与えられた文字列の長さを取得して,10万回加算する関数を作ってみました.この関数をFirefox,IE,Google Chromeで走らせて処理時間を計測してみます.

実験ソースコード

データ型を利用する場合

function useData(st){
???? var startTime = new Date();
???? var s = st;
???? var num=0;
???? for(var i = 0; i < 100000;i++){
          num+=s.length;
???? }
???? document.write(new Date() - startTime);
}

オブジェクトを利用する場合

function useObject(st){
???? var startTime = new Date();
???? var s = new String(st);
???? var num=0;
???? for(var i = 0; i < 100000;i++){
          num+=s.length;
???? }
???? document.write(new Date() - startTime);
}

実験結果

それぞれの場合で実行時間を計測してみたものを書きに示しています.実行するたびに処理時間は違うので,数値は参考程度にして欲しいのですが,私が気になったのは,Firefoxの場合はデータ型で処理する方が早いけど,IEの場合はオブジェクトで処理する方が早いって言うこと.

Firefox 3の場合

文字列型を用いた場合の平均処理時間:102 msec Stringオブジェクトを用いた場合の平均処理時間:11 msec

何度か実行したが,圧倒的に,Objectを利用して処理した方が10倍程度速い.

Internet Explorer 7の場合

文字列型を用いた場合の平均処理時間:30 msec Stringオブジェクトを用いた場合の平均処理時間:27 msec

何度か実行しましたが,ほとんど変わりませんでした.

Google Chromeの場合

GoogleChromeの場合,実行速度が速すぎてよくわからないので,ループを1000万回に変更して実行しました.

文字列型を用いた場合の平均処理時間:92 msec Stringオブジェクトを用いた場合の平均処理時間:102 msec

何度か実行してみましたが,文字列型を利用して処理した方が1割ほど早いようです.

考察

私の予想では,オブジェクトで処理するよりも,文字列型で処理する方が早いと思っていたのですが,FirefoxおよびIEでは,Stringオブジェクトで処理した方がよさそう,という結果になってしまいました.

こうなる原因がわからないのは気持ち悪いので,軽く調べてみたところ,JavaScriptにおいてs.lengthのように,オブジェクト指向風にメソッドを呼び出す書き方をすると,文字列型であった変数sが内部的にStringオブジェクトに変換されるようです.

そもそも,私が文字列型のほうが早いと思った理由って,lengthにアクセスしようとした瞬間に,文字列長を都度計算しているからだと思ったんですが,調べてみるとlengthはオブジェクトのプロパティとして持っているみたいなんですよね.つまり,Firefoxの場合において,文字列型の方が遅いのは文字列型からオブジェクトへの変換の際のオーバーヘッドがそのまま処理時間に表れてきている気がします.

まぁ,それぞれのブラウザの速度差については,実装の違いと言ってしまえばそれまでなのかもしれません.Google Chromeの場合のみ,文字列型で処理した方が速いのが不思議ですが,JavaScriptエンジンの高速化の効果なのでしょうか.次世代Firefox,IE8では,実験結果が変わってくるのかもしれません.