2016-04-15 6 views
0

大きな配列を使用して数値(1000以上のサイズ)を格納する場合、この配列値はy軸線グラフをリアルタイムで描画するために使用されます。ビッグデータセットのJavascript配列unshiftおよびpop操作

私は常にunshiftこの配列を新しいデータを追加し、pop配列の最後のデータを削除します。この操作により、グラフは左から右に移動できます。

ただし、この方法は簡単ですが、配列サイズが大きくなり、グラフが1つ以上ある場合は、アレイ)。この操作を行うためのより良い方法があることは知っていますか?

+1

実際に配列操作のパフォーマンス上の問題がありますか、これは単なる理論的なものですか?グラフの描画は、どのアレイ操作よりもはるかに時間がかかります。 JavaScriptでの配列は、JSエンジンでは必ずしも標準配列ではないことに気をつけてください。それらは、 'unshift'や' pop'演算を実行するためのリストやツリーとして実装できます。 –

+0

は理論的な質問であり、この操作をすると特にメモリ断片化の問題が気になります...私は他のより良い選択肢を探したいと思います.. – Tim

+1

'unshift'はパフォーマンスがあまり良くなく、' push'なので 'push'と'unshift'と' pop'の代わりに 'shift'を使い、逆に配列を読み込みます。逆の読書もまっすぐな読書よりも速いと信じていますまた、これをチェックしてください.. http://code.stephenmorley.org/javascript/queues/ – Redu

答えて

1

この問題の二つの側面があります。

は、この操作を行うに任意のより良い方法はありますか?

どのようにグラフを描画するかによって大きく異なります。あなたはそれのために何らかのライブラリを使いますか?もしそうなら、おそらく特定のデータ(例えば、配列)を期待しているので、それについてはあまりできません。一方、あなた自身で描画部分を実装している場合は、必要な任意のデータ構造(ここで適切なリストを含む)を使用することができます。

メモリの断片化とArrayパフォーマンス

すべての最初の質問を自問してください:あなたが実際にArray操作で任意のパフォーマンスの問題を持っているか、これは単なる理論であるのですか?

グラフの描画は、どのアレイ操作よりもはるかに時間がかかります。私は実際に問題がなければ、Arrayメソッドのパフォーマンスについて心配するべきではないと思います。 JSエンジンでArrayであるということは必ずしも配列として実装されているとは限りません。バイナリ検索ツリーやそれを使用する方法によっては、バイナリ検索ツリーやその他のものでもあります。したがって、どの最適化があなたのケースでうまくいくかを予測するのは難しく、状況を悪化させます。

パフォーマンスを向上させる方法はありますか?

はい。しかし、どのように実際に配列を使用するかによって異なります。ライブグラフを描くと想像できます。unshift/popデータなどです。 1秒ごとに正確に配列のlengthを知っていますか?それは一定のままでなければなりません。したがって、最初に行うことのできることの1つは、その長さの配列にメモリを割り当てることです。エンジンで最適化するのは簡単なケースなので、将来はunshift + popを実行すると、メモリが断片化することはありません。しかし、もう一度、それはちょうど推測です。JavaScriptエンジンは私がよりスマートです。より多くのヒントとテクニックは、記事Let’s get those Javascript Arrays to work fastに記載されています。

壊れていないものを修正しようとしないでください。リファクタリングを開始する前に測定し、あまりにも詳しく考える必要はありません。これは時期尚早の最適化と呼ばれ、実際にアプリケーションを実行しているときに配列操作で最適化することは重要ではないということは肯定的です。

+0

素敵な答え!、それは実際にそのリンクは、私はこの考えに私を取得し、リンクは 'unshift'と'ポップ '操作はメモリの断片化を引き起こすことはありません割り当てられた言及? – Tim

+0

エンジンで最適化するのは簡単なケースなので、私は言いませんでした。しかし、現時点では実際には何が起こるか分からないので、コードベースで自分自身をチェックする必要があります。 –

1

私は従来の同じメモリのコピーに対してシフト/プッシュを測定するのに不思議で、結果はかなり明確であり、最適化は必要ありません。

var p = [], q = []; 
 
for (var i = 0; i < 10000; i++) p[i] = i; 
 
for (var i = 0; i < 10000; i++) q[i] = i; 
 

 
function rotate_1(a, x) { 
 
    var len = a.length; 
 
    for (var i = 1; i < len; i++) 
 
    a[i - 1] = a[i]; 
 
    a[len - 1] = x; 
 
} 
 

 
function rotate_2(a, x) { 
 
    a.shift(); 
 
    a.push(x); 
 
} 
 

 
t = new Date() 
 
for (var i = 0; i < 100000; i++) rotate_1(p, i); 
 
document.write("copy="); 
 
document.write(new Date() - t); 
 
document.write("<br>"); 
 

 
t = new Date() 
 
for (var i = 0; i < 100000; i++) rotate_2(q, i); 
 
document.write("shift/push="); 
 
document.write(new Date() - t); 
 
document.write("<br>");

+0

これは実際にはかなり面白いです。実際に大規模な配列で操作する場合は、配列に 'push 'して反復を開始するインデックスを増やすほうが速いでしょうか?あるいは、要素を追加する前に最初に要素を削除する方が良いでしょうか? 2番目のメソッドはメモリの断片化を引き起こすべきではなく、定数インデックス(この場合は0)から始まるループは、JSエンジンによってさらに最適化されます。 –

+1

@MichałMiszczyszyn:おっと、私は質問を誤読するように見えます。彼はラウンドロビンではなく、毎回新しいデータを追加したいと考えています。 – georg

+1

@MichałMiszczyszyn:編集済み... – georg

関連する問題