JAVA中int数组上非顺序迭代的低性能
我有以下功能:JAVA中int数组上非顺序迭代的低性能,java,arrays,performance,Java,Arrays,Performance,我有以下功能: public void scanText(char[] T){ int q=0; for(int i=0;i<T.length;i++){ q = transFunc[preCompRow[q]+T[i]]; if(q==pattern.length){ System.out.println("match found at position: "+(i-pattern.length+2));
public void scanText(char[] T){
int q=0;
for(int i=0;i<T.length;i++){
q = transFunc[preCompRow[q]+T[i]];
if(q==pattern.length){
System.out.println("match found at position: "+(i-pattern.length+2));
}
}
}
public void扫描文本(char[]T){
int q=0;
对于(inti=0;i一种可能的解释是,由于内存访问模式的局部性差,代码的内存性能很差
在现代计算机中,内存缓存的作用是处理处理器指令时间(小于1ns)和主内存(5到10ns或更多)之间的速度不匹配。当代码从内存中获取的缓存命中率最高时,它们工作得最好
现代Intel芯片组以64字节的块缓存内存,并以突发模式从主存加载(对应于16int
值)。I7处理器上的一级缓存为2MB
如果您的应用程序能够按顺序(大致)访问大型阵列中的数据,则8次访问中有7次是缓存命中。如果访问模式是非顺序的,并且的“工作集”是缓存大小的大倍数,则每次内存访问都可能会导致缓存未命中
如果内存访问区域性是yoiur问题的根源,那么您的选择是有限的:
- 重新设计算法,使内存引用的局部性更好
- 购买具有较大缓存的硬件
- (可能)重新设计您的算法以使用GPU或其他策略来减少内存流量
在C或C++中记录你的存在可以提高性能,但是同样的内存位置问题也会影响到你。
我不知道有什么工具可以用来测量Java应用程序中的缓存性能。定义“非常慢”。我不认为java访问数组是件很慢的事情。?你的ram怎么样?也许你的ram中有所有的内存,操作系统交换了很多,所以它会转到磁盘来获取你的数组位置。用几个字符试试,看看性能如何,而不使用太多的ram。@Andreas我用8324701在一个字符数组上搜索了4000种不同的模式然后我运行了相同的测试,但我更改了transFunc[preCompRow[q]+T[I]
fortransFunc[T[I]]
只花了9秒。@leoxs我在两个测试的执行过程中没有看到任何交换活动。我正在使用2 GB的heapI。你真的需要性能,你可以用C编写代码,并将其作为java项目中的一个模块使用。如果可以并行运行,可以考虑使用线程,或者更好,在GPU上这样做。我还认为bottleneck在+,但我测试了几个案例transFunc[T[I]]
,transFunc[1+T[I]]
,transFunc[T[I]]
,所有这些都有合理的性能,但每次我在索引中添加预编译行[q]时,整个事情都会出错。当我将q
修正到某个值时,事情会非常快,例如transFunc>[preCompRow[1]+T[I]]
。我的结论是问题在于q
的值,在循环的每一次过程中,它可以取模式的1到#个字符之间的值。我认为您的思路是正确的。因为T
值是char
,它们可能被限制为ASCII,即在32到126的数字范围内。transFunc[T[i]]
将只访问transFunc
的索引,整个范围(总共760字节)将很快在一级缓存中。--对于transFunc[preCompRow[q]+T[i]]
,我们不知道preCompRow
值的范围,即transFunc
的大小,但如果该值很大,则将其加载到一级缓存需要更长的时间,甚至可能超过L1
缓存的大小,从而大大增加缓存未命中率,即使对于相同的索引值也是如此。是的,我认为问题与缓存有关。preComRow
只是一个模式大小的int数组。行是预计算的,因为我使用2D数组作为转换函数,但表示为1D数组(我认为我在JAVA 2D数组模拟方面有问题),然后形式为arr[I][j]的数组表示为arr[(I*步数)+j],我对此进行了预计算,以避免搜索循环中的计算。问题是我知道preCompRow
的范围。我忘了提到,我正在搜索的模式非常短,只有50个字符长。如果您为您的问题创建MCVE,以便我们可以观察并诊断“缓慢访问”,这将对我们有所帮助如果没有一个适当的MCVE,我认为除了猜测之外,不可能做任何事情。