所以对于我的研究小组,我试图将一些旧的C++代码,Java和正在运行到一个问题,即在C++代码,它执行以下操作:优化Java数组复制
method(array+i, other parameters)
现在我知道, Java不支持指针算术,所以我通过将array + i的子数组复制到一个新数组的末尾来解决这个问题,但这会导致代码运行非常慢(即比C++版本慢100倍)。有没有办法解决这个问题?我看到有人在这里提到了一个内置的方法,但更快吗?
所以对于我的研究小组,我试图将一些旧的C++代码,Java和正在运行到一个问题,即在C++代码,它执行以下操作:优化Java数组复制
method(array+i, other parameters)
现在我知道, Java不支持指针算术,所以我通过将array + i的子数组复制到一个新数组的末尾来解决这个问题,但这会导致代码运行非常慢(即比C++版本慢100倍)。有没有办法解决这个问题?我看到有人在这里提到了一个内置的方法,但更快吗?
不仅你的代码变慢,它还改变了正在发生的事情的语义:当你用C++进行调用时,不会进行数组复制,因此任何改变method
都可能适用于原来发生的数组,不在丢弃副本中。
要达到同样的效果在Java中改变你的函数的签名如下:
void method(array, offset, other parameters)
现在调用者必须通过数组中的立场,即method
应该考虑的“虚零”阵列。换句话说,而不是写类似
for (int i = 0 ; i != N ; i++)
...
,你会写
for (int i = offset ; i != offset+N ; i++)
...
这将保持C++语义将数组传递给一个成员函数。
C++函数可能依赖于从array
开始的处理。在Java中,它应该配置为从偏移量运行到数组中,因此不需要复制数组。复制阵列,即使使用System.arraycopy
,也需要花费大量的时间。
它可以像这样的东西被定义为一个Java方法:
void method(<somearraytype> array, int offset, other parameters)
然后,该方法将在偏移到数组开始,它会被称为是这样的:
method(array, i, other parameters);
如果您希望将子数组传递给某个方法,则可以将该子数组复制到新数组中的替代方法是使用额外的offset
参数传递整个数组,该参数指示数组的第一个相关索引。这需要更改method
的实施,但如果性能问题,这可能是最有效的方法。
来处理这个正确的方法是重构的方法,采取签名
method(int[] array, int i, other parameters)
让你通过整个阵列(参考),然后告诉方法从哪里开始其处理。那么你不需要做任何复制。
你在使用'System.arraycopy()'吗? – Eran 2014-09-30 18:00:38
不,我刚刚手动复制到一个新的子阵列。是System.arraycopy()显着紧固? – 2014-09-30 18:02:26
正如答案所指出的那样,等价的Java惯用法是将引用传递给原始数组以及开始索引。核心的JDK类充满了这种用法的例子 - 接受数组的许多方法都被重载,以接受数组和开始/结束索引以在数组的片上操作。看看例如'字符串(char []值)'与字符串(char []值,int偏移量,int计数)' – Alex 2014-09-30 18:11:37