2014-03-31 102 views
0

長時間讀者,第一次張貼海報。MappedByteBuffer初始運行緩慢

我在從一組二進制文件中快速讀取數據時遇到了一些麻煩。 ByteBuffers和MappedBytBuffers提供我需要的性能,但它們似乎需要初始運行來預熱。我不知道如果是有道理的所以這裏的一些代碼:

int BUFFERSIZE = 864; 
int DATASIZE = 33663168; 

int pos = 0; 
// Open File channel to get data 
FileChannel channel = new RandomAccessFile(new File(myFile), "r").getChannel(); 

// Set MappedByteBuffer to read DATASIZE bytes from channel 
MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_ONLY, pos, DATASIZE); 

// Set Endianness 
mbb.order(ByteOrder.nativeOrder()); 

ArrayList<Double> ndt = new ArrayList<Double>(); 

// Read doubles from MappedByteBuffer, perform conversion and add to arraylist 
while (pos < DATASIZE) { 
    xf = mbb.getDouble(pos); 
    ndt.add(xf * cnst * 1000d + stt); 
    pos += BUFFERSIZE; 
} 

// Return arraylist 
return ndt; 

因此,這需要大約7秒運行,但如果我再運行它它爲10ms。它似乎需要做一些初始運行來設置正確的行爲。我發現,通過做一些簡單的像這樣工作的:

channel = new RandomAccessFile(new File(mdfFile), "r").getChannel(); 
ByteBuffer buf = ByteBuffer.allocateDirect(DATASIZE); 
channel.read(buf); 
channel.close(); 

這需要2秒左右,如果我再通過MappedByteBuffer程序運行在10ms的返回數據。我無法弄清楚如何擺脫初始化步驟,並在第一次10ms內讀取數據。我已經閱讀了各種有關'熱身',JIT和JVM的事情,但都無濟於事。

所以,我的問題是,是否可以立即獲得10毫秒的性能,還是需要進行某種初始化?如果是這樣,請這樣做最快的方法是什麼?

該代碼旨在運行通過大約一千個相當大的文件,所以速度非常重要。

非常感謝。

+0

嘿,你_do_需要第一次從文件中讀取... – fge

+0

哇,那很快!謝謝。第一次閱讀的最快方法有什麼想法? – jonesds

+0

恩,我不知道這是否真的是你的問題的答案,但你可以使用'MappedByteBuffer'的'.load()'方法將映射加載到內存中;如果你可以在後臺加載'.load()',那麼你可以獲得時間 – fge

回答

1

我只是無法弄清楚如何擺脫初始化步驟,並在10ms的首次

您無法讀取數據。數據必須從磁盤讀取。這需要超過10毫秒。當它已經在內存中時,所有其他時間都是10ms。