0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Swift/SwiftUI】@Pulishedで監視された配列の要素追加に対する考察

Posted at

はじめに

@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の操作は、
非常に高速であり、あまり考慮する必要がなさそうでした

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?