著名なサイトのこのコード。
actor BackgroundImporter {
var modelContainer: ModelContainer
init(modelContainer: ModelContainer) {
self.modelContainer = modelContainer
}
func backgroundInsert() async throws {
let modelContext = ModelContext(modelContainer)
let batchSize = 1000
let totalObjects = 100_000
for i in 0..<(totalObjects / batchSize) {
for j in 0..<batchSize {
// try await Task.sleep(for: .milliseconds(1))
let issue = Movie(title: "Movie \(I * batchSize + j)", cast: [])
modelContext.insert(issue)
}
try modelContext.save()
}
}
}
ここの部分。
// try await Task.sleep(for: .milliseconds(1))
説明としては以下のように書いています。
It has a commented-out 1-millisecond pause between each object insertion – the code goes as fast as possible, but if you want to throttle your inserts you should uncomment that line.
各オブジェクトの挿入の間にコメントアウトされた 1 ミリ秒の一時停止があります。コードは可能な限り高速に実行されますが、挿入を抑制したい場合は、その行のコメントを解除する必要があります。
怪しいですよね。
試してみます。
🤔 やってみたが
似たコードがあったのでデータ10万行で試してみました。
少し思ったことをいくつか。
🧑🏻💻 なぜこのコメントアウト行を書いたのか
自然に考えると不要ですよね。
「挿入を抑制したい場合」の意味については、
著者は書いてません。
が、コメントアウトのままでは、
途中で画面に反映されなかった。
実行環境に依る話しなのかもしれません。
表面的にデリケートな奥深い話しなのでしょうか。
🧑🏻💻 sleep のタイミング
数十万レコードを処理してみたのですが、遅すぎる。
どっちみち、メインスレッドに反映のタイミングは、
try modelContext.save()
なので、
for i in 0..<(totalObjects / batchSize) {
for j in 0..<batchSize {
let issue = Movie(title: "Movie \(I * batchSize + j)", cast: [])
modelContext.insert(issue)
}
try modelContext.save()
try await Task.sleep(for: .milliseconds(1)) // *
}
のが実行時間的には早いし、
save()
のタイミングで画面反映もされる。
まさか、insert の順序が交差してしまうのか ?
🧑🏻💻 @ModelActor
を使う
こここそ使うところなんじゃね?
@ModelActor
actor BackgroundImporter {
func backgroundInsert() async throws {
let batchSize = 1000
let totalObjects = 100_000
for i in 0..<(totalObjects / batchSize) {
for j in 0..<batchSize {
let issue = Movie(title: "Movie \(I * batchSize + j)", cast: [])
modelContext.insert(issue)
}
try modelContext.save()
try await Task.sleep(for: .milliseconds(1))
}
}
}
呼び出し側。
@Environment(\.modelContext) private var modelContext
private var importer: BackgroundImporter {
BackgroundImporter(modelContainer: modelContext.container)
}
actor 側で、いきなり、modelContext
を使ってますが、
イニシャライザーなどマクロが書き出してますので
Xcode から expand で見ることができます。
🤔 まとめ
などやっていると、怖くなってきます SwiftData。
【SwiftUI + SwiftData】ScrollView + LazyVStack vs Large amounts of data https://t.co/I79u1tkDkw #Swift #プログラミング学習
— chanzmao (@maochanz) June 27, 2024
Emerge Tools ブログ | SwiftData と Realm: パフォーマンス比較 https://t.co/M1smRe0GNX
— chanzmao (@maochanz) June 25, 2024