大容量の配列をループする JavaScript の効率は満足のいくものではありません。以前、VBS 配列と比較したことがありますが、VBS の配列ループ速度は JS よりもおよそ 1 桁高速でした。 asp?id=4313487 )。一般的なプログラミングでは、JS 配列の効率にはあまり注意を払いません。要素が数十個しかない配列の効率を知ることさえできませんが、ノードの数は数千、数万など多数になります。大量の配列ループが使用される場合、効率の問題が主に考慮されるべき問題になります。大容量配列の検索には一般に、コンボ ボックス選択時の高速マッチング、ツリー クエリ、テーブルの並べ替えや検索などの用途があります。
まず、大容量の配列
<SCRIPT LANGUAGE="JavaScript">
を作成します。
var n = 100000; //配列の最大容量
var a = 新しい配列();
for(var i=0; i<n; i++)
{
a[i] = Math.random() +"";
}
</SCRIPT>
このようにして、長さ 100000 の文字配列を作成し、0.9999 で始まる文字列を取得して別の配列に格納しました。
<スクリプト言語="JavaScript">
var n = 100000; //配列の最大容量
var a = 新しい配列();
for(var i=0; i<n; i++)
{
a[i] = Math.random() +"";
var
begin = new Date().getTime();
var b = 新しい配列();
for(var i=0; i<n; i++)
{
if(a[i].indexOf("0.9999")==0)
{
b[b.length] = a[i];
}
}
document.write("配列の長さ: "+ n);
document.write("<br>従来のループ方式では時間がかかる" + (new Date().getTime() - begin)
+" ミリ秒! 検索結果: <strong title=""+ b.join(" ")
+">'>「+ b.length +」レコードを取得しました!</strong>");
</SCRIPT>
このステップの処理には約 2800 ミリ秒かかります。説明すると、このループは if 判定と代入演算だけです。ここでの判定はもう少し複雑です。桁違いに時間がかかります。では、この問題に対する適切な最適化ソリューションはあるのでしょうか?答えはもちろんイエスです。そうでなければ、この投稿で私が言うことはすべて言葉の無駄になってしまいます。しかし、従来の考え方ではこれより良い記述方法が見つからないため、この問題を最適化するために従来の考え方を使用することはできなくなりました。
解決策は、まず配列を join() して大きな文字列にし、次に正規表現を使用して大きな文字列を照合して取得することです。この方法は、ツリーを作成する過程で思いついた私の個人的なオリジナリティと言えますが、効率は悪くありません。 join() の効率についてはすでに説明しました ( http://blog.csdn.net/meizz/archive/2005/12/14/552260.aspx JavaScript Speed: The Efficiency of Combining and Splicing Strings)。この最適化計画には、一定レベルの正規表現スキルが必要です。
<input id="count" value="50000" size="7" maxlength="6">
<input type="button" value="配列初期化" onclick="txt.innerHTML = array_init()"><br>
<input type="button" value="従来のループ" onclick="txt.innerHTML += method_for()">
<input type="button" value="通常のマッチング" onclick="txt.innerHTML += method_regexp()">
<div id="txt"></div>
<スクリプト言語="JavaScript">
var txt = document.getElementById("txt");
var a = 新しい Array()
関数 array_init();
{
var n = parseInt(document.getElementById("count").value);
a.長さ = 0;
for(var i=0; i<n; i++)
{
a[i] = Math.random() +"";
}
"配列の長さ: "+ n; を返します。
関数
メソッド_for()
{
var n = a.length;
var begin = new Date().getTime();
var b = 新しい配列();
for(var i=0; i<n; i++)
{
if(a[i].indexOf("0.9999")==0)
{
b[b.length] = a[i];
}
}
return ("<br>従来のループ方式では時間がかかる" + (new Date().getTime() - begin)
+" ミリ秒! 検索結果: <strong title=""+ b.join(" ")
+">'>「+ b.length +」レコードを取得しました!</strong>");
関数
メソッド_regexp()
{
var begin = new Date().getTime();
var b = 新しい配列();
var s = a.join("x0f");
var r = new RegExp().compile("0\.9999\d+", "g");
b = s.match(r);
return ("<br>通常のマッチング方法には時間がかかります" + (new Date().getTime() - begin)
+" ミリ秒! 検索結果: <strong title=""+ b.join(" ")
+">'>「+ b.length +」レコードを取得しました!</strong>");
}
</SCRIPT>
テストして、上記の 2 つの方法の効率の違いがどれだけあるかを確認できます。コードは死んでいますが、人々は生きています。考え方やモデルを変えると効率が大きく変わります。
このトリックを思いつくまでにはかなりの頭を使いましたが、これを共有するのは非常に気が進まないのですが、2006 年の新年の始まりを皆さんにお祝いしたいと思います。