"abc".x(2) -> "abcabc"
配列に続いて、文字列の乗算メソッドも実装してみましょう。ただし、全然違うアルゴリズムを用います。
String.prototype.x = function (x) { var base = this, result = ''; while (x) { if (x % 2) result += base; x = Math.floor(x / 2); base += base; } return result; };
KaoriYa.net さんの BBS ブラウザ "Chalice" の文字列乗算関数 (AL_string_multiplication in alice.vim) からほぼそのまま拝借しています。
どういう理屈か説明しますと、要はビット演算なんですね。1 回のループで要素を倍のサイズに、なおかつループカウンタを 2 で割っています。このことが言わば左ビットシフトとして機能するんです。そして、
if (x % 2)
というのがビットが立っている状態を表すことになります。
ビットの繰上げとオン・オフの検出が、余分な変数を使わずに実現できていて、非常に巧みだと思います。
で、これがどれほど速いかと言いますと、とにかくループの回数が激減するわけです。つまり、ビットの数だけしか回りません。
例えば 32 は 2 の 5 乗で、2進表記すると 6 桁になります (100000)。したがって、カウンタ (引数 x) が 32 から 63 までの場合、ループの回数はわずかに 6 回で済む、ということです。素晴らしいですよね。
ただ、配列でもこの手法を試してみたんですが、私がテストした限りでは効果が見られませんでした。おそらく、大きなサイズの配列を 1 回 push するのに結構労力がかかるので、単純ループの場合とほとんど差が出ないということなんでしょう。