残念な話。 ―配列への循環アクセス 2―
昨日のエントリ( 感嘆した話。 ―配列への循環アクセス― )について、早速テストしてみました。
短い配列を循環しながら、長い配列にコピーしていくという処理で計ってみます。
今回も、JavaScriptで書きます。
まず、時間を計る関数を準備。
関数functionObjectを、functionCount回実行して、かかった時間(ms)の平均を返します。
function getTheFuncTime(functionObject, functionCount) { // :Number var start, end; functionCount = functionCount || 1; start = new Date(); for(var i=0; i<functionCount; i++) { functionObject(); } end = new Date(); return (end - start) / functionCount; }
コピー元、コピー先の配列を準備。
var sourceArray = []; var sourceArrayLength = 10; var destinationArray = []; var destinationArrayLength = 100000; for (var i=0; i<sourceArrayLength; i++) { sourceArray.push(Math.random()); }
if文方式で循環する関数test01。
function test01() { // :void var currentIndex = 0; for (var i=0; i<destinationArrayLength; i++) { destinationArray.push(sourceArray[currentIndex]); if(++currentIndex >= sourceArrayLength) { currentIndex = 0; } } destinationArray = []; }
余り方式で循環する関数test02。
function test02() { // :void var currentIndex = 0; for (var i=0; i<destinationArrayLength; i++) { destinationArray.push(sourceArray[currentIndex]); currentIndex = ++currentIndex % sourceArrayLength; } destinationArray = []; }
test01とtest02で違うところ
for文内の
if(++currentIndex >= sourceArrayLength) { currentIndex = 0; }
と
currentIndex = ++currentIndex % sourceArrayLength;
のみですね。
そして、ここが今回のテストの勘所でもあります。
では、いよいよ計ってみます。
コメントに、とある回の出力を示します。
console.log('if文方式: ' + getTheFuncTime(test01, 5) + 'ms'); // if文方式: 468.6ms console.log('余り方式: ' + getTheFuncTime(test02, 5) + 'ms'); // 余り方式: 512.6ms
結果
何度か計測した中では100%、「if文方式」の方が「余り方式」よりも良いパフォーマンスが得られました。
それぞれの配列の個数を変えても、概ね同じ比率です。
また、console.logをalertにしてIEでも計測してみましたが、実装による違いもないようです。
感想
新しい書き方(余り方式)を知ってテンションが上がっていた自分には残念な結果でしたが、よい勉強になりました。
エレガントというか、プログラムっぽい書き方(自分はそう思うのですが…)が必ずしも速いというわけではない。
でも、こういう構文糖にはもっとたくさん出会って、柔軟にプログラミング出来るようになりたいです。
今回の余り方式だって、他に使いどころがあるかも知れないし。
「そもそもテストの仕方がおかしいぞ!」などなどあれば、ツッコミ頂ければ幸いです><