【问题标题】:java - Loop optimization on int arrayjava - int 数组的循环优化
【发布时间】:2018-05-22 12:29:05
【问题描述】:

我想知道,在 int 数组中写入/读取的快速方法。

这是我的 Java 代码:我有三个 int 数组,两个用于读取访问权限,一个 int 数组用于写入访问权限。

for(int j = h20 ; j < h21 ; j++){
    for(int i = w20 ; i < w21 ; i++){
        if( int_color == arr3[j*h31 + i] )  continue; //condition 
        arr1[(j+decY)*w11 + i+decX] = arr2[j*w21 + i];      
    }   
}

我的代码是一个经典的二维数组循环,只有一个特殊条件需要检查。

是否有其他方法可以编写此代码以减少处理时间?

谢谢。

【问题讨论】:

  • "是否有其他方法可以编写此代码以减少处理时间?" 因为您需要 ij,即使您可以合并循环,你仍然需要h21 * w21 迭代。所以不会有太大变化。现在,根据逻辑(我们这里没有所有数据)也许你可以简化一下。
  • 除非您找到一种方法来减少索引计算中的操作数量,否则我会说这是尽可能优化的。您可以在进入第二个循环之前执行所有依赖于j的操作,这样每个内部循环只需计算一次这些值。
  • 您应该反转 if 语句的条件并删除 continue
  • 不,不可能改变逻辑,我知道问题是全局内存复制的障碍。

标签: java loops optimization


【解决方案1】:

如果您用变量分隔它们,您可以减少计算量。在您的情况下,任何仅依赖 j 的计算都不必在内部循环内,因为结果在循环的其余部分不会改变。相反,计算 outside 的值,并且只使用内部循环中的结果。

for(int j = h20 ; j < h21 ; j++){
    int tmp1 = j*h31;
    int tmp2 = (j+decY)*w11 + decX;
    int tmp3 = j*w21;

    // j won't change inside here, so you can simply use the precalculated values
    for(int i = w20 ; i < w21 ; i++){
        if( int_color == arr3[tmp1 + i] )  continue; //condition 
        arr1[tmp2 + i] = arr2[tmp3 + i];      
    }   
}

编辑:如果你想进一步减少这个,你可以重写tmp2的计算:

(j+decY)*w11 + decX ==> j*w11 + decY*w11 + decX

然后,您可以在第一个循环之外将decY*w11 + decX 提取到它自己的变量中。

int tmp0 = decY*w11 + decX;
for(int j = h20 ; j < h21 ; j++){
    int tmp1 = j*h31;
    int tmp2 = j*w11 + tmp0;
    int tmp3 = j*w21;

    // j won't change inside here, so you can simply use the precalculated values
    for(int i = w20 ; i < w21 ; i++){
        if( int_color == arr3[tmp1 + i] )  continue; //condition 
        arr1[tmp2 + i] = arr2[tmp3 + i];      
    }   
}

但这只会为您每次迭代节省一次添加,所以我认为不值得付出额外的努力。

【讨论】:

  • 是的,你说得对,我忘了这条路。我不是 JAVA 专家,我认为专家方法是迭代器或其他专注于 JAVA 方法的方法。
  • 您的优化似乎没问题,但它们可能没用,因为 JIT 编译器也知道这些技巧。
【解决方案2】:

删除计算,尤其是乘法可能会有所帮助。

对于 arr3 这将是:

final int icolor = int_color;
final int ix3 = h20 + w20;
final int dx3 = h31 + h21 - h20;

for (int j = h20; j < h21; ++j) {
    for (int i = w20 ; i < w21 ; ++i) {
        assert ix3 == j*h31 + i;
        if (icolor != arr3[ix3]) {
            arr1[(j+decY)*w11 + i+decX] = arr2[j*w21 + i];
        }
        ++ix3;
    }
    ix3 += dx3;
}

这是否真的值得一试。

根据条件出现的频率,人们可能会想到将System.arraycopy 用于 i 的连续范围。

【讨论】:

  • 你的ix3j * h31 + i,你不能在循环之外评估它,你需要ij。在这里,您每次都检查相同的值。
  • @AxelH 对,我忘了在内部循环中增加 ix3。已更正
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2023-03-30
  • 1970-01-01
相关资源
最近更新 更多