4

DBからデータを取得するためにJavaプログラムを使用しています。次に、いくつかの数値を計算し、それらを配列に格納し始めます。私が使用しているマシンには 4 ギガの RAM があります。さて、事前にいくつになるか分からないのでArrayList<Double>.300 million numbers.

したがって、1 つの double は 8 バイトであるため、この配列が消費するメモリの概算は 2.4 ギガです (おそらく ArrayList のオーバーヘッドのため、それ以上になります)。この後、この配列の中央値を計算したいので、配列org.apache.commons.math3.stat.descriptive.rank.Medianを入力とするライブラリを使用していますdouble[]したがって、 を に変換する必要がありArrayList<Double>ますdouble[]

これが提起された多くの質問を見ましたが、それらはすべて、配列全体をループする方法はないと述べています。これで問題ありませんが、両方のオブジェクトをメモリ内に維持するため、メモリ要件は最大 4.8 ギガになります。利用可能な RAM の合計が 4 GB であるため、問題が発生しました。

まず第一に、プログラムがある時点で正しいメモリエラーを与えるという私の疑いはありますか(現在実行中です)?もしそうなら、2倍のメモリを割り当てずに中央値を計算するにはどうすればよいですか? 中央値の計算は O(n) であるため、配列の並べ替えを避けたいと考えています。

4

4 に答える 4

2

プリミティブの動的配列を作成する多くのオープン ソース ライブラリがあります。これらのいずれか: http://trove.starlight-systems.com/

于 2013-11-10T11:20:38.883 に答える
1

同意します。Trove4jTDoubleArrayListクラス ( javadocを参照) を使用して double またはTFloatArrayListfloat を格納します。以前の回答を組み合わせると、次のようになります。

// guess initialcapacity to remove requirement for resizing
TDoubleArrayList data = new TDoubleArrayList(initialcapacity);
// fill data
data.sort();
double median = data.get(data.size()/2);
于 2013-11-10T12:09:20.837 に答える
1

中央値は、ソートされたリストの中央の値です。したがって、2 番目の配列を使用する必要はありません。次のようにするだけです。

Collections.sort(myArray);
final double median = myArray.get(myArray.size() / 2);

とにかくDBからそのデータを取得するので、Javaで行う代わりにDBに中央値を与えるように指示するだけで、データを送信するための時間(およびメモリ)も節約できます。

于 2013-11-10T11:06:40.640 に答える