2014-09-30 73 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) 

讓你通過整個陣列(參考),然後告訴方法從哪裏開始其處理。那麼你不需要做任何複製。