譯 Swift 上的高效能陣列

2021-09-11 09:06:03 字數 1915 閱讀 3089

譯文出自:掘金翻譯計畫

譯者:jingzhilehuakai

校對者:rickeyboy

cbangchen

對於日常應用開發,考慮陣列效能是一件不會經常發生的事。如果你正在實現需要擴充套件的演算法,也許高效能陣列就能出現在你腦海中。也許你正在寫更偏向於底層的**,比如乙個框架,這時任何的效能缺陷都會產生復合效應。當陣列效能變得重要的時候,了解一些優化陣列效能的方式也是很不錯的。讓我們來深入的了解一下 swift 中的陣列吧。

型別。和名字所暗示的不同,它其實是 swift 中最簡單的陣列型別。相比標準的陣列,它可以有更好的效能表現,而即便沒有,也至少可以提供與array相同效能水平的表現。同時也暴露出相同的介面。所以,為什麼不用contiguousarray去替代array呢?

let deliciousarray = contiguousarray(arrayliteral: "?", "?", "?")複製**
好吧,因為 objective-c 的相容性,array能無縫對接成乙個nsarray。在底層,乙個array例項只要它的元素型別是 class 或是遵循了 objective-c 相容協議的型別,就會將陣列資料儲存在nsarray中。只要不是這種情況(例如陣列元素為值型別的陣列),這個陣列就不會被儲存在nsarray中,並且效能變得和contiguousarray相當。

為了比較效能,我們執行了這樣乙個測試,向每個陣列的例項中新增一百萬個單獨的引用型別,然後刪除。這些引用型別會在開始計時前進行預構建,而結果為超過 100 次的執行後得到的平均值。下面的值是在設定了編譯器優化的情況下獲得的。總的來說,你可以看到,如果陣列效能是瓶頸的話,在陣列元素為引用型別或@objc型別的前提下,切換為contiguousarray的使用大約能獲得 2 倍效能的提公升。

arraycontiguousarray

58.9 ms

30.3 ms

看起來 swift 陣列分配的記憶體與它的長度成正比。如果是這種情況,新增或刪除乙個元素將需要分配或釋放記憶體,並對陣列長度的每乙個變化都造成效能損失。相反,提前分配最少的記憶體空間是更有意義的,這樣就可以在不引起記憶體管理效能損失的情況下進行接下來的幾個新增操作。這實際上是 swift 所做的:以一種智慧型的方式進行記憶體分配,來讓分配效能消耗保持在最低的水平。

儘管有智慧型記憶體分配,但如果清楚地知道陣列應該被定義持有的記憶體大小,才是記憶體分配最有效的方式。這樣,只需要乙個記憶體分配就可以了。 swift 陣列提供了定義和預留容量的能力,而且這樣做可以實現較小的效能增益。

var healthyarray = ["?", "?"]

healthyarray.reservecapacity(50)複製**

執行另乙個測試,再次向乙個陣列中新增和刪除一百萬個引用型別,產生以下的結果。該測試是針對連續陣列有無預留記憶體容量的情況。

without reserved capacitywith reserved capacity

29.7 ms

27.3 ms

如果你想訪問原始記憶體來加強陣列,你也可以這麼做。對於標準的陣列操作,它不會提供太多的效能增益。對於非標準的情況,用這種方式訪問或修改資料可能是有必要的,或者是對效能有益的。

var balanceddietarray = ["?", "?", "?"]

balanceddietarray.withunsafemutablebufferpointer 複製**

高效能的索引策略(上)

高效的選擇和使用索引有很多方式,其中有些事針對特殊案例的優化方法,有些則是針對特定行為的優化,使用哪個索引,以及如何評估選擇不同索引效能影響的技巧,則需要持續不斷的練習。接下來將介紹如何高效的使用索引。獨立的列 我們通常會看到一些查詢不當的使用索引,或者是的mysql無法使用已有的索引。如果查詢中的...

亂譯《高效能MySQL(第二版)》 前言

前言 我了解到peter,vadim和arjen已經在他們自己和客戶的專案中使用mysql相當一段時間了。在這方面,baron有編寫了一些客戶端工具用以改進mysql的易用性。作者的從業背景已經反映出他們在本書第二版中所做的工作,效能優化,可複製性,備份等等。這本書不僅僅告訴你如何提高你在優化mys...

高效能的OkHttp

預設情況下,okhttp並沒有將包含cache control頭部檔案的響應進行快取。因此你的客戶端可能會浪費時間與頻寬去重複請求相同的資源,而不是簡單地讀取初次請求時候的快取副本。為了保證基於檔案系統的響應快取,應該配置乙個com.squareup.okhttp.cache例項並且把它傳遞給okh...