2014-09-30 77 views
1

所以对于我的研究小组,我试图将一些旧的C++代码,Java和正在运行到一个问题,即在C++代码,它执行以下操作:优化Java数组复制

method(array+i, other parameters) 

现在我知道, Java不支持指针算术,所以我通过将array + i的子数组复制到一个新数组的末尾来解决这个问题,但这会导致代码运行非常慢(即比C++版本慢100倍)。有没有办法解决这个问题?我看到有人在这里提到了一个内置的方法,但更快吗?

+1

你在使用'System.arraycopy()'吗? – Eran 2014-09-30 18:00:38

+0

不,我刚刚手动复制到一个新的子阵列。是System.arraycopy()显着紧固? – 2014-09-30 18:02:26

+1

正如答案所指出的那样,等价的Java惯用法是将引用传递给原始数组以及开始索引。核心的JDK类充满了这种用法的例子 - 接受数组的许多方法都被重载,以接受数组和开始/结束索引以在数组的片上操作。看看例如'字符串(char []值)'与字符串(char []值,int偏移量,int计数)' – Alex 2014-09-30 18:11:37

回答

6

不仅你的代码变慢,它还改变了正在发生的事情的语义:当你用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++语义将数组传递给一个成员函数。

2

C++函数可能依赖于从array开始的处理。在Java中,它应该配置为从偏移量运行到数组中,因此不需要复制数组。复制阵列,即使使用System.arraycopy,也需要花费大量的时间。

它可以像这样的东西被定义为一个Java方法:

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

然后,该方法将在偏移到数组开始,它会被称为是这样的:

method(array, i, other parameters); 
0

如果您希望将子数组传递给某个方法,则可以将该子数组复制到新数组中的替代方法是使用额外的offset参数传递整个数组,该参数指示数组的第一个相关索引。这需要更改method的实施,但如果性能问题,这可能是最有效的方法。

0

来处理这个正确的方法是重构的方法,采取签名

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

让你通过整个阵列(参考),然后告诉方法从哪里开始其处理。那么你不需要做任何复制。