在JAVA中的int数组的非顺序迭代中的低性能

时间:2017-06-11 01:07:59

标签: 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));
        }
    }
}

此函数扫描char数组,搜索给定模式的匹配项,该模式存储为有限自动机。自动机的转换函数存储在名为transFunc的变量中。

我正在使用800万个字符并使用800000个模式的文本中测试此功能。事情是数组preCompRow [q](这是一个int [])的加入非常慢。如果我删除代码的preCompRow [q],性能会大大提高。我认为这可能是因为在每个循环中,q变量具有不同的非顺序值(2,56,18,9 ......)。

有没有更好的方法以非顺序方式访问数组?

提前致谢!

1 个答案:

答案 0 :(得分:1)

一种可能的解释是,由于内存访问模式的位置不佳,您的代码会看到内存性能不佳。

现代计算机中内存缓存的作用是处理处理器指令时间(小于1 ns)和主内存(5到10 ns或更长)之间的速度不匹配。当代码在从内存中获取的大部分时间内获得缓存时,它们的效果最佳。

现代英特尔芯片组以64字节为单位缓存内存,并以突发模式从主内存加载。 (这相当于16个int值。)(比如说)I7处理器上的L1缓存是2MB。

如果您的应用程序能够按顺序(大致)按顺序访问大型数组中的数据,则8次访问中的7次将是缓存命中。如果访问模式是非顺序的并且“工作集”是高速缓存大小的大倍,那么最终可能会在每次内存访问时出现高速缓存未命中。

如果内存访问位置是yoiur问题的根源,那么您的选项是有限的:

  • 重新设计算法,以便内存引用的位置更好
  • 购买带有更大缓存的硬件
  • (可能)重新设计您的算法以使用GPU或其他策略来减少内存流量

重新编码现有的C或C ++可能会提高性能,但同样的内存位置问题也会让你感到困扰。

我不知道有任何工具可用于衡量Java应用程序中的缓存性能。