始めに
以下のような処理を書いたときに、パフォーマンス面で問題がないか気になったため、調査してみることにしました。
let contensCount = realm.objects(Content.self).count
Results Are Lazy
Realm only runs a query when you actually request the results of that query. This lazy evaluation enables you to write elegant, highly performant code for handling large data sets and complex queries. You can chain several filter and sort operations without requiring extra work to process the intermediate state.
Realmでオブジェクトがロードされるタイミングについて
- プロパティアクセス時
let dogs = realm.objects(Dog.self) // 🙅♀️
let name = dogs[0].name // 🙆♀️
- イテレーション時
let dogs = realm.objects(Dog.self)
for dog in dogs { // 🙆♀️
print(dog.name)
}
* 配列変換時
let dogs = realm.objects(Dog.self)
let array = Array(dogs) // 🙆♀️
* クロージャ処理時
let dogs = realm.objects(Dog.self)
let names = dogs.map { $0.name } // 🙆♀️
Countは全件のデータを読み込んでカウントしているわけではないので、パフォーマンスに問題なかったです
let contensCount = realm.objects(Content.self).count
Resultsはライブであることに注意
Results to a query are not copies of your data: modifying the results of a query will modify the data on disk directly. This memory mapping also means that results are live: that is, they always reflect the current state on disk.
一度クエリを実行して取得した Results は、データベースの変更を自動かつリアルタイムで反映してくれます。その特性を活かすためにも、設計時には更新のタイミングや参照の仕方に注意が必要です。
let results = realm.objects(Content.self)
print(results.count) // この時点ではA件
try! realm.write {
realm.add(Content(...)) // 追加
}
print(results.count) // 自動でB件に更新される
終わりに
RealmのResultsが遅延評価される仕組みにより、効率的な処理が行われていることがわかりました。ただし、全件読み込みを伴う処理では注意が必要な場面もあるため、常にデータの扱い方を意識しながら設計していきたいと思います。