2016-03-08 49 views
-1

我喜歡第二種情況,因爲它將相關的代碼保存在一個地方,但是如果我這樣做,那麼每次評估閉包時都會重新計算常量?Swift - 計算閉包內的不可變性效率低下嗎?

let numCols = 99 

// case 1 
let spacing = (width - margin.left - margin.right)/(numCols - 1) 
let xCoord = { (Int: col) -> Float in margin.left + col * spacing } 

// case 2 
let xCoord = { (Int: col) -> Float in 
    let spacing = (width - margin.left - margin.right)/(numCols - 1) 
    return margin.left + col * spacing 
} 

回答

3

簡短答案是肯定的,計算閉包內的不可變是無效的。

這是爲什麼。比方說,你有這樣的代碼:

let numCols = 99.0 
let width = 800.0 
let marginLeft = 15.0 
let marginRight = 20.0 

// case 1 
let spacing: Double = (width - marginLeft - marginRight)/(numCols - 1) 
let xCoord1 = { (col: Double) -> Double in 
    return marginLeft + col * spacing 
} 

// case 2 
let xCoord2 = { (col: Double) -> Double in 
    let spacing: Double = (width - marginLeft - marginRight)/(numCols - 1) 
    return marginLeft + col * spacing 
} 

這些都是例1和例2從你的榜樣,一點修改遊樂場編譯。

讓我們做一個簡單的for循環來衡量這些功能執行每2500次:我的機器上

let startTime = CACurrentMediaTime() 
for var i in 0...2500 
{ 
    xCoord1(10) 
} 
let totalTime = CACurrentMediaTime() - startTime 
print("time: - \(totalTime) sec") 

案例中0.99秒1個執行(可以是一個有點不同的,如果你有更高或更低的硬件特性)。

現在,讓我們看看我們得到了什麼,如果我們做同樣的情況下2:在我的機器,這意味着它比情況下,效率較低的1.49秒

let startTime2 = CACurrentMediaTime() 
for var i in 0...2500 
{ 
    xCoord2(10) 
} 
let totalTime2 = CACurrentMediaTime() - startTime2 
print("time: - \(totalTime2) sec") 

案例2個執行1.

因此,如果你有恆定的寬度,邊距和列數,最好一次計算間隔並將其存儲在常量中。 但是,如果您不必多次重複此計算並只需要一次,則仍然可以將其保留在閉包中以便於閱讀。 在您的上下文中播放測量性能代碼,看看您是否失去了性能,並據此作出決定。