2013-06-23 47 views
4

我從文件中加載了一個2D數組,它是15,000,000 * 3個整數(最終將是40,000,000 * 3)。現在,我使用dataInputStream.readInt()來順序讀取整數。它需要約15秒。我可以使其顯着(至少3倍)更快,或者這個速度可以達到我能得到的速度嗎?什麼是從文件中加載大2D二維int數組的最快方法?

+0

想想如何將陣列布置在內存中。內存是1D ... – theunamedguy

+0

@HovercraftFullOfEels我當然是緩衝:) – fhucho

+1

40密耳* 3英寸* 4個字節每個int = 480 MB。您的驅動器可以多快讀取這麼多數據? – Lyth

回答

7

是的,你可以。benchmark of 13 different ways of reading files

如果你必須選擇最快的方法,這將是其中之一:

  • FileChannelMappedByteBuffer和陣列讀取。使用ByteBuffer和數組讀取。
  • FileChannel與包裝數組ByteBuffer和直接數組訪問。

對於最好的Java讀取性能,有4件事情要記住:

  • 通過 一次讀取陣列的時間,而不是字節最小化I/O操作。一個8KB的數組是一個很好的大小(這就是爲什麼它是BufferedInputStream的默認值)。
  • 通過一次獲取數組數據來最小化方法調用,而不是一次一個字節 。使用數組索引來獲取數組中的字節。
  • 如果您不需要線程 安全性,請最小化線程同步鎖。要麼對線程安全類進行更少的方法調用,要麼使用 非線程安全類如FileChannelMappedByteBuffer
  • 儘量減少JVM/OS,內部緩衝區和應用程序陣列之間的數據複製。使用帶有內存映射的FileChannel,或直接使用 或包裝數組ByteBuffer
7

將您的文件映射到內存!

Java 7的代碼:

FileChannel channel = FileChannel.open(Paths.get("/path/to/file"), 
    StandardOpenOption.READ); 
ByteBuffer buf = channel.map(0, channel.size(), 
    FileChannel.MapMode.READ_ONLY); 

// use buf 

詳情請參閱here

如果你使用Java 6,你必須:

RandomAccessFile file = new RandomAccessFile("/path/to/file", "r"); 
FileChannel channel = file.getChannel(); 
// same thing to obtain buf 

,你甚至可以在緩衝區使用.asIntBuffer()如果你想。當你需要閱讀時,你只能閱讀你實際需要閱讀的內容。 它不影響你的堆。

+0

如果我能接受兩個答案,這也是一個很好的答案,upvoted。 – fhucho

相關問題