我需要优化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