2017-07-14 28 views
0

我工作的一個項目,我需要用大型陣列工作,並通過使用UnsafeMutablePointers,我得到了使用普通陣列方法三倍的速度增加。但是,我認爲寫入行爲的副本會導致我更改不想受到影響的實例。例如,在下面的代碼中,我想更新copyArray中的值,但將原始值保留在anArray中。有沒有辦法重寫Swift數組的寫入時複製行爲?

import Foundation 

func increaseWithPointers(_ arr: inout [Int]) { 
    let count = arr.count 
    let ptr = UnsafeMutablePointer(mutating: &arr) 
    for i in 0..<count { 
     ptr[i] = ptr[i] + 1 
    } 
} 

var anArray = [1,2,3,4,5] 
var copyArray = anArray 

increaseWithPointers(&copyArray) 
print(anArray) 

執行此代碼打印[2,3,4,5,6]。

我可以通過聲明copyArray如下解決這個問題:

var copyArray = [Int](repeating: 0, count: 5) 
for i in 0..<5 { 
    copyArray[i] = anArray[i] 
} 

然而,這需要每個寫值的兩倍:到零,然後到預定值。有沒有辦法有效保證數組的副本?

+1

不是用'UnsafeMutablePointer'的加速的原因,這是*不*做的寫的副本?換句話說,通過使用「UnsafeMutablePointer」,你已經「重寫了Swift數組寫入行爲的副本」。如果你想在寫入時複製,只需刪除'UnsafeMutablePointer'並在提供的'inout [Int]'上完成工作。或者只是做'anArray.map {$ 0 + 1}' – BallpointBen

+1

有趣。我運行你的代碼並得到'[1,2,3,4,5]'作爲輸出。 –

+0

在實際的代碼中,對陣列執行的操作更爲廣泛,這就是爲什麼我需要使用指針來提高速度的原因。但是,我需要將操作限制在副本的上下文中。 –

回答

1

我可以使用Xcode的9測試版3,但沒有使用的Xcode 8.3.3重現您的問題。我建議你提交一份Swift bug report

這解決了這個問題:

import Foundation 

func increaseWithPointers(_ arr: inout [Int]) { 
    arr.withUnsafeMutableBufferPointer { (buffer) in 
     for i in buffer.indices { 
      buffer[i] += 1 
     } 
    } 
} 

var anArray = [1,2,3,4,5] 
var copyArray = anArray 

increaseWithPointers(&copyArray) 
print(anArray) 
+0

你是對的工作時,Xcode 9B3表現不同。不知'讓PTR = UnsafeMutablePointer(不同誘變:&ARR)'被「允許」在所有的,因爲它產生一個指向元件存儲有可能成爲無效。 –

+0

同意; 'UnsafeMutableBufferPointer(mutating:)'的原始使用是未定義的行爲。沒有承諾,它指向任何特別的東西(甚至有效的記憶)。在這裏使用'withUnsafeMutableBufferPointer'是必需的(雖然不能保證所需的性能)。 –

+0

真棒,謝謝。我會提交一份報告。它似乎是一個Swift 4問題。 –

相關問題