简体   繁体   English

优化Java阵列复制

[英]Optimizing Java Array Copy

So for my research group I am attempting to convert some old C++ code to Java and am running into an issue where in the C++ code it does the following: 因此,对于我的研究小组,我尝试将一些旧的C ++代码转换为Java,并遇到一个问题,其中在C ++代码中它执行以下操作:

    method(array+i, other parameters)

Now I know that Java does not support pointer arithmetic, so I got around this by copying the subarray from array+i to the end of array into a new array, but this causes the code to run horribly slow (Ie 100x slower than the C++ version). 现在我知道Java不支持指针算术,因此通过将子数组从array + i复制到数组的末尾到新数组中来解决了这个问题,但是这导致代码运行缓慢(即比C ++慢100倍)版)。 Is there a way to get around this? 有办法解决这个问题吗? I saw someone mention a built-in method on here, but is that any faster? 我看到有人在这里提到一个内置方法,但是这样更快吗?

Not only does your code become slower, it also changes the semantic of what is happening: when you make a call in C++, no array copying is done, so any change the method may apply to the array is happening in the original, not in the throw-away copy. 您的代码不仅变慢,而且还改变了正在发生的事情的语义:当您在C ++中进行调用时,不会进行数组复制,因此,可能应用于该数组的任何method更改都发生在原始数组中,而不是在数组中。一次性的副本。

To achieve the same effect in Java change the signature of your function as follows: 要在Java中达到相同的效果,请按如下所示更改函数的签名:

void method(array, offset, other parameters)

Now the caller has to pass the position in the array that the method should consider the "virtual zero" of the array. 现在,调用者必须传递数组在该method应考虑数组“虚拟零”的位置。 In other words, instead of writing something like 换句话说,而不是写类似

for (int i = 0 ; i != N ; i++)
    ...

you would have to write 你将不得不写

for (int i = offset ; i != offset+N ; i++)
    ...

This would preserve the C++ semantic of passing an array to a member function. 这将保留将数组传递给成员函数的C ++语义。

The C++ function probably relied on processing from the beginning of the array . C ++函数可能依赖于array开头的处理。 In Java it should be configured to run from an offset into the array so the array doesn't need to be copied. 在Java中,应将其配置为从偏移量运行到数组中,因此不需要复制数组。 Copying the array, even with System.arraycopy , would take a significant amount of time. 即使使用System.arraycopy ,复制数组也要花费大量时间。

It could be defined as a Java method with something like this: 可以将其定义为具有以下内容的Java方法:

void method(<somearraytype> array, int offset, other parameters)

Then the method would start at the offset into the array, and it would be called something like this: 然后,该方法将从数组的偏移量开始,并将其命名为:

method(array, i, other parameters);

If you wish to pass a sub-array to a method, an alternative to copying the sub-array into a new array would be to pass the entire array with an additional offset parameter that indicates the first relevant index of the array. 如果希望将子数组传递给方法,则将子数组复制到新数组中的另一种方法是将整个数组与附加offset参数一起传递,该参数指示数组的第一个相关索引。 This would require changes in the implementation of method , but if performance is an issue, that's probably the most efficient way. 这可能需要更改method的实现,但是如果性能是一个问题,那可能是最有效的方法。

The right way to handle this is to refactor the method, to take signature 解决此问题的正确方法是重构方法,获取签名

method(int[] array, int i, other parameters)

so that you pass the whole array (by reference), and then tell the method where to start its processing from. 这样就可以传递整个数组(通过引用),然后告诉该方法从何处开始对其进行处理。 Then you don't need to do any copying. 然后,您无需进行任何复制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM