我需要優化csv文件(字符串)的實際加載/解析。我知道的最好的方法是就地加載算法,並且我成功地使用了JNI和一個C++ dll,它直接從一個由解析的csv數據構成的文件中加載數據。java字符串優化 - 就地加載算法
如果它停在那裏,它會好起來的,但是使用該方案只會使速度提高15%(不再解析數據)。其中一個原因並不像我第一次想到的那樣快,因爲java客戶端使用jstring,所以我需要再次將實際數據從char *轉換爲jstring。
最好的辦法是忽略該轉換步驟並將數據直接加載到jstring對象中(不再進行轉換)。因此,不是基於現場加載的數據來複制數據,而是將jstring直接指向內存塊(請注意,數據將由jchars而不是字符組成)。真正的壞處是,我們需要確保垃圾收集器不會收集數據(通過保持對它的引用可能?),但它應該是可行的。
我想我有兩個選擇這樣做:
1加載Java中的數據(不超過JNI),並使用都指向加載的數據創建串字符..但我需要找到一種方法來防止在創建字符串時複製數據。
2-繼續使用jni「手動」創建並設置jstring變量,並確保垃圾收集器選項設置正確,以防止它做任何事情。例如:
jstring str;
str.data = loadedinplacedata; // assign data pointer
return str;
不知道這是可能的,但我不介意只是直接保存的jstring到文件並重新加載它這樣:
jstring * str = (jstring *)&loadedinplacedata[someoffset];
return * str;
我知道,這是不是通常的Java事情,但我非常確定Java可擴展性足以做到這一點。並不是說我真的有這個選擇......項目已經3年了,需要運作。 = S
這在JNI代碼(C++):
const jchar * data = GetData(id, row, col); // get pointer of the string ends w/ \0
unsigned int len = wcslen((wchar_t*)data);
// The best would be to prevent this function to duplicate the data.
jstring str = env->NewString(data, len);
return str;
注:上面的代碼使它更快(而不是15)20%通過使用Unicode數據代替UTF8(NewString代替NewStringUTF) 。這表明,如果我可以刪除該步驟或優化它,我會獲得相當不錯的性能提升。
這是從哪裏來的?如果拷貝花費的時間比磁盤IO長,假設沒有什麼真正的愚蠢行爲,我會感到驚訝。 –
- 1)您是否需要將整個文件同時存儲在內存中? - 2)爲什麼要使用JNI? – claymore1977
它通常是在開發環境中從.jar文件和文件直接加載的。所以你可以假設幾乎沒有磁盤IO,因爲它應該已經被加載了。 我不需要它在內存中的所有文件,但文件應該已經存在,因爲它是jar文件的一部分。 JNI讓我使用指針...但是由於我用C++有更多的xp,我可能會誤解一些Java的特性。有什麼辦法可以防止數據的複製(如根據內存中的位置重新使用引用?) – MasterPlanMan