はじめに
@Pulishedで装飾された配列(Array)は中身が変更されるたびに、
Viewに対して変更通知が送られます
そのため複数の要素を追加する際、都度apendする
のかまとめて別リストで置き換える
のでどちらがパフォーマンスに優れるか気になったので、考察しました
結論
結論からいくとまとめて別リストで置き換える
方が優れています
やはりappendするたびに、View更新通知を送られるのがネックのようです
解説
以下のソースを例にします
class ContentViewModel: ObservableObject {
// 対象の配列。このitemを何かしらのViewが参照しているとして下さい
@Published var items: [String] = []
// ①都度apendするパターン
func addItemsWithAppend() {
for i in 0..<100 {
// このappendのたびにViewへの通知が発生する可能性がある!
// 100回ループすれば、100回の更新通知が飛ぶことに…
self.items.append("Item \(i)")
}
}
// ②新規でリストを作成して置き換えするパターン
func addItemsOnce() {
// 新しい配列を作成する
var newItems = self.items
for i in 0..<100 {
newItems.append("Item \(i)")
}
// Viewへの通知はここで一度だけ発生する
self.items = newItems
}
}
争点となるのはappendされたときのviewの更新であり、
描画更新が行われるのでコストが重いです
そのため都度appendする場合、forでループした分更新通知を送られる可能性があるそうです
補足
では仮に@Publishedで装飾されていない場合、
どうパフォーマンスが違うか気になったので調べました
結論から行くとほどんど変わらないそうです
@Publishedを取り除くと、Viewへの通知コストがないので、
純粋なSwiftの配列操作の違いとなります
Swfitの配列操作は非常に最適化されているため、
どちらでも内部処理は変わらないようです
他の言語においてもappend
の操作は、
非常に高速であり、あまり考慮する必要がなさそうでした