我的java数组代码表现得很滑稽

我的java数组代码表现得很滑稽,java,algorithm,sorting,optimization,compiler-optimization,Java,Algorithm,Sorting,Optimization,Compiler Optimization,我正在研究一个算法,我一直在成功地优化它,直到我遇到这个奇怪的问题: 数组C作为参数传递给方法 int lim = C.length; double A[]=new double[lim]; double B[]=new double[lim]; for (int I = offset; I < lim; I++) { A[ (int) B[C[I]] ] = C[I]; } int lim=C.长度; 双A[]

我正在研究一个算法,我一直在成功地优化它,直到我遇到这个奇怪的问题:

数组C作为参数传递给方法

       int lim = C.length; 
      double A[]=new double[lim];
      double B[]=new double[lim];
      for (int I = offset; I < lim; I++) {
      A[ (int) B[C[I]] ] = C[I];
      }
int lim=C.长度;
双A[]=新双[lim];
双B[]=新双[lim];
对于(int I=偏移;I
A
B
double
数组,
C
是整数数组。它们的大小都一样。
当我使用
System.nanoTime()
发现时间差时,我注意到这段代码的运行速度要慢得多

通过故障排除,我发现如果我仅用
I
或一个常量或任何变量替换
C[I]
,它的运行速度比它的值来自代码中未预定义的源时快很多倍

作为最后一次测试,我用一个随机整数替换了
C[I]
,得到了同样的慢速。发生了什么事?JVM是否为预定义变量优化代码?我能合理地解决这个问题而不在代码中定义数组的内容吗(我相信这会解决这个问题)

如果我能解决这个问题,优化将产生一个新的排序算法,它的运行速度将比Java7实现的快速排序算法快得多。对于许多类型的输入,它的速度已经超过了n<8000左右


目前,我已经(在我的机器上)记录了它在3.8-3.9秒内对800万个数字(键入double)进行排序,而Java的QuickSort
实现(Arrays.sort())
在同一台机器上大约在1.53秒内完成。我在2个for循环中跟踪了这一行代码的2次事件,我需要帮助。

我怀疑是内存局部性问题导致了速度的减慢

当您拥有非常大的阵列时,它们将跨越多个(虚拟内存)页面。因此,如果您试图以非顺序方式访问阵列元素,那么最终访问内存的方式可能会抵消硬件用于快速访问内存的“智能”的影响:

  • 如果你访问很多不同的位置,它们就不再适合缓存了。这会导致缓存未命中,CPU必须从物理内存中提取数据,这会减慢速度

  • 访问的非顺序性意味着宽内存获取对性能没有帮助

  • 当这些位置分散在大量页面上时,您很可能会在TLB(翻译查找缓冲区)硬件中出现未命中。。。它缓存vm页面条目。TLB未命中通常会导致更多的内存访问,以从内存中读取页表条目


很难说这是否真的是导致您的算法变慢的原因。(尽管我认为你们的实验结果支持这一主张…)


如果这是潜在的问题,那么你对此无能为力。这是现代计算机工作的固有方式。如果您的算法需要在足够大的阵列上进行“随机”访问,那么性能将受到物理内存速度的限制。

我怀疑是内存位置问题导致了性能下降

当您拥有非常大的阵列时,它们将跨越多个(虚拟内存)页面。因此,如果您试图以非顺序方式访问阵列元素,那么最终访问内存的方式可能会抵消硬件用于快速访问内存的“智能”的影响:

  • 如果你访问很多不同的位置,它们就不再适合缓存了。这会导致缓存未命中,CPU必须从物理内存中提取数据,这会减慢速度

  • 访问的非顺序性意味着宽内存获取对性能没有帮助

  • 当这些位置分散在大量页面上时,您很可能会在TLB(翻译查找缓冲区)硬件中出现未命中。。。它缓存vm页面条目。TLB未命中通常会导致更多的内存访问,以从内存中读取页表条目


很难说这是否真的是导致您的算法变慢的原因。(尽管我认为你们的实验结果支持这一主张…)


如果这是潜在的问题,那么你对此无能为力。这是现代计算机工作的固有方式。如果您的算法需要在足够大的阵列上进行“随机”访问,那么性能将受到物理内存速度的限制。

我怀疑是内存位置问题导致了性能下降

当您拥有非常大的阵列时,它们将跨越多个(虚拟内存)页面。因此,如果您试图以非顺序方式访问阵列元素,那么最终访问内存的方式可能会抵消硬件用于快速访问内存的“智能”的影响:

  • 如果你访问很多不同的位置,它们就不再适合缓存了。这会导致缓存未命中,CPU必须从物理内存中提取数据,这会减慢速度

  • 访问的非顺序性意味着宽内存获取对性能没有帮助

  • 当这些位置分散在大量页面上时,您很可能会在TLB(翻译查找缓冲区)硬件中出现未命中。。。它缓存vm页面条目。TLB未命中通常会导致更多的内存访问,以从内存中读取页表条目


很难说这是否真的是导致您的算法变慢的原因。(尽管我认为你们的实验结果支持这一主张…)

如果这是潜在的问题,那么就没有什么可以做的了