0

ここやネット上に同様のスレッドがいくつかあったことは知っていますが、何か間違ったことをしているようです. 私の仕事は簡単です-整数の大きな配列(int []またはArrayListまたはあなたが最善だと思うもの)をファイルに書き込みます(そして後で読み取ります)。速いほど良い。私の具体的な配列には約4.5Mの整数があり、現在の時間は次のとおりです(ミリ秒単位):

  • 生成トライ: 14851.13071
  • 配列の生成: 2237.4661619999997
  • 配列の保存: 89250.167617
  • 配列の読み込み: 114908.08185799999

これは容認できないことであり、時間はもっと短くすべきだと思います。私は何を間違っていますか?地球上で最速の方法は必要ありませんが、これらの時間を約 5 ~ 15 秒にすることが私の目標です。

私の現在のコード:

long start = System.nanoTime();

Node trie = dawg.generateTrie("dict.txt");
long afterGeneratingTrie = System.nanoTime();
ArrayList<Integer> array = dawg.generateArray(trie);
long afterGeneratingArray = System.nanoTime();

try
{
    new ObjectOutputStream(new FileOutputStream("test.txt")).writeObject(array);
}
catch (Exception e)
{
    Logger.getLogger(DawgTester.class.getName()).log(Level.SEVERE, null, e);
}
long afterSavingArray = System.nanoTime();

ArrayList<Integer> read = new ArrayList<Integer>();
try
{
    read = (ArrayList)new ObjectInputStream(new FileInputStream("test.txt")).readObject();
}
catch (Exception e)
{
    Logger.getLogger(DawgTester.class.getName()).log(Level.SEVERE, null, e);
}
long afterLoadingArray = System.nanoTime();

System.out.println("Generating trie: " + 0.000001 * (afterGeneratingTrie - start));
System.out.println("Generating array: " + 0.000001 * (afterGeneratingArray - afterGeneratingTrie));
System.out.println("Saving array: " + 0.000001 * (afterSavingArray - afterGeneratingArray));
System.out.println("Loading array: " + 0.000001 * (afterLoadingArray - afterSavingArray));
4

2 に答える 2

3

Java シリアライゼーションを使用しないでください。非常に強力で堅牢ですが、特に高速 (またはコンパクト) ではありません。シンプルなDataOutputStream呼び出しを使用しますwriteInt()。(必ず と のBufferedOutputStreamDataOutputStreamを使用してくださいFileOutputStream)。

読み取り時に配列のサイズを事前に設定する場合は、最初の int を配列の長さとして書き込みます。

于 2012-09-11T18:39:52.197 に答える
0

Something like the following is probably a fairly fast option. You should also use an actual array int[] rather a ArrayList<Integer> if you're concern is reducing overhead.

final Path path = Paths.get("dict.txt");
...
final int[] rsl = dawg.generateArray(trie);
final ByteBuffer buf = ByteBuffer.allocateDirect(rsl.length << 2);

final IntBuffer buf_i = buf.asIntBuffer().put(rsl).flip();
try (final WritableByteChannel out = Files.newByteChannel(path,
    StandardOpenOptions.WRITE, StandardOpenOptions.TRUNCATE_EXISTING)) {
  do {
    out.write(buf);
  } while (buf.hasRemaining());
}

buf.clear();
try (final ReadableByteChannel in = Files.newByteChannel(path,
    StandardOpenOptions.READ)) {
  do {
    in.read(buf);
  } while (buf.hasRemaining());
}
buf_i.clear();
buf_i.get(rsl);
于 2012-09-11T19:04:18.747 に答える