数组的直接访问

3
为了加快我的图像处理应用程序的速度,我试图从中间开始处理数组值,并使用以0开始的索引。例如,当我处理两个数组时,通常会出现这样的情况:
public void work(int[] array1, int[] array2, int offset)
{
    int len = array1.length;
    for (int i = 0; i < len; i++)
        array1[i] += array2[i + offset];
}

我想创建一个新的变量array3,它直接映射到array2的中间位置(不是副本),这样我就可以这样做:

public void work(int[] array1, int[] array2, int offset)
{
    int[] array3 = array2[offset]...;
    int len = array1.length;
    for (int i = 0; i < len; i++)
        array1[i] += array3[i];
}

实际上,我想要一个Java等价于这个C语句:
int *array3ptr = array2ptr + offset;

注意:我没有使用JNI或其他类似技术的经验,所以如果需要使用,请提供可行的示例。

这是当前的性能问题吗?你想要替换循环内的单个加法操作吗? - Greg Kopff
3个回答

1

使用纯Java数组和array[index]符号无法实现此操作。在Java数组中,永远不可能重叠

但是,您可以将数组包装在{{link1:IntBuffer}}中。如果使用{{link2:直接缓冲区}}(请参见{{link3:allocateDirect}}),则应该获得真正的良好性能。

例如,以下语句

int *array3ptr = array2ptr + offset;

应该写成

IntBuffer array3 = array2.slice().position(offset);

这些


只有在将数据移动到某个地方(磁盘、网络)而不仅仅是在内存中操作时,直接缓冲区才能提高性能。但是,如果您的处理过程包括从磁盘读取、操作、写回,则直接缓冲区可以帮助提高性能。 - Greg Kopff
很遗憾,我不是将数据整体移动,而是在pel级别(即像素中的单个颜色)进行操作。查看DirectByteBuffer的源代码,我发现get方法检查越界,计算索引并从Unsafe对象获取值。这只能比array[x + variable]慢得多。 - Mark Jeronimus
在得出结论之前先试一下。array[x + variable] 也会执行数组边界检查。 - aioobe
我时间很紧,而且我已经实现了数组版本。在找到时间更改可行的东西之前,需要一段时间。现在,我的应用程序瓶颈是GUI,而不是图像处理。 - Mark Jeronimus
大家看看Zom-B,他已经对他的应用程序进行了分析,以确保他将优化工作放在瓶颈上。这与过早优化相反。这是一个非常出色的做法 :-) - aioobe
显示剩余2条评论

0
在Java中,即使是整数数组也是堆上的对象。因此,int[] array2实际上直接引用内存中的整数数组。不会创建对象(即数组)的副本,只会复制对数组的引用。

0

我对它们没有太多经验,但我认为你可以通过将数组(和子数组)包装到IntBuffer实例中来实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接