火曜日, 6月 3, 2025
- Advertisment -
ホームニューステックニュース【iOS】もしかしてRealmのせいでビルド遅い? #Swift - Qiita

【iOS】もしかしてRealmのせいでビルド遅い? #Swift – Qiita



【iOS】もしかしてRealmのせいでビルド遅い? #Swift - Qiita

iOS 開発でローカルでのデータ永続化を行うための選択肢として、UserDefaultsRealmがよく挙げられると思います。
Realmは高性能なローカルストレージで売り出されているので、高速での読み書きを行いたい場合などはよく使われていると思っています。
ただ、WWDC23 でSwiftDataという Apple 純正の高機能ローカルストレージライブラリが登場したことで、高性能なローカルストレージの新たな選択肢として、SwiftDataも挙がるようになりました。
今まで私は、業務ではもちろん、個人開発する時もRealmをよく使っていましたが、SwiftDataもいつか使ってみたいなーとか思っていました。

そんな中あるいつものように Realm を使っていると、ちょっとした違和感を感じました。
みなさんも、Realm を使っていてこんな経験はないでしょうか?

違和感

ビルド遅くない?
Preview の表示遅すぎ

今まで Realm 以外にもたくさんのライブラリに依存したアプリ開発が多かったので、たくさんのライブラリに依存しているからそりゃ遅くなるよねっと考えていました。

ただ、最近ビルド速度を計測する方法を覚えたので、個人アプリのビルド速度を測ってみたら驚きの事実が判明しました。

ビルドのタイムラインを見てみると、ビルドプロセスのほぼ半分は Realm 関連のコードのコンパイルに使われていたのです。(以下赤枠部分)
image.png

ざっくり時間を見てみると、4min ぐらい使っています。
image.png
image.png

この結果を見ると、今まで Realm に依存しているプロジェクトが何だかビルド時間遅い気がしていたのは、Realm によるところが大きいのでは?と思えてきました。

仮説

RealmからSwiftDataに移行したら、ビルド速度爆速になるのでは?

試してみる

検証方法

SPM で、以下構成のサンプルプロジェクトを作って、検証してみます。
それぞれの要素を一つのモジュールと捉えてください。
image.png

簡単に構成の説明をすると、
RealmClientRealmSwiftに依存したアプリケーションを実装するモジュールで、このモジュールをビルドすると、Realmを含んだアプリをビルドすることになります。

SwiftDataClientSwiftDataに依存したモジュールで、ビルドするとSwiftDataを含めてビルドすることになります。

両方で同じUIに依存しているので、それぞれのモジュールで違うのは、どのローカルストレージライブラリに依存しているかだけです。

つまり、RealmClientSwiftDataClientのビルド速度を比較することで、今回の仮説を検証できます。

検証結果

結果は以下の通りで、SwiftDataClientのビルド速度が圧倒的に早かったです。

モジュール 依存ライブラリ ビルド速度
RealmClient Realm 82.5s
SwiftDataClient SwiftData 2.6s

仮説②

@externvoid@github (extern void)さんのコメントを受けて、先ほどの検証は同じ条件ではなくビルド速度の比較方法として適切でなさそうということに気づきました。(コメントありがとうございます!!)

SwiftDataは標準のSDKにコンパイル済みのバイナリとして同梱されているので、ビルド時にコンパイルは行わないのに対して、RealmはSPMでソースコードをチェックアウトしているだけでビルド時にはコンパイルから行わないといけないので、SwiftDataの方が圧倒的にビルド速度が速くなることは自明でありました。

そのため、同じ条件で(両ライブラリをコンパイル済みのバイナリにして)RealmClientSwiftDataClientのビルド速度を比較すると、ほとんど変わらないのではないか?
というコメントをいただきましたので、仮説②として確認してみました!

検証方法

SPMでRealmに依存するときに、GithubリポジトリのURLを使うのではなく、XCFrameworkを取得して、binaryTargetとしてRealmに依存するようにします。

XCFrameworkは、リポジトリのリリースノートからCarthage用のXCFrameworkを拝借しました。

ダウンロードしたzipを展開して、Realm.xcframeworkRealmSwift.xcframeworkPackage.swiftbinaryTargetとして定義して、依存するようにします。

Package.swift

// swift-tools-version: 6.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: “LocalStoragePeformanceExample”,
platforms: [.iOS(.v18), .macOS(.v15)],
products: [
.library(
name: “SampleUI”,
targets: [“SampleUI”]
),
.library(
name: “RealmClient”,
targets: [“RealmClient”]
),
.library(
name: “SwiftDataClient”,
targets: [“SwiftDataClient”]
)
],
targets: [
.target(
name: “SampleUI”
),
.target(
name: “RealmClient”,
dependencies: [
“SampleUI”,
“RealmModel”
]
),
.target(
name: “SwiftDataClient”,
dependencies: [
“SampleUI”,
“SwiftDataModel”
]
),
.target(
name: “RealmModel”,
dependencies: [
“RealmSwiftBinary”,
“RealmBinary”
]
),
.binaryTarget(
name: “RealmSwiftBinary”,
path: “RealmSwift.xcframework”
),
.binaryTarget(
name: “RealmBinary”,
path: “Realm.xcframework”
),
.target(name: “SwiftDataModel”)
]
)

上記手順で、RealmをXCFrameworkとして依存することで、コンパイルせずにビルドできるようになるので、SwiftDataと同じ条件でビルド速度を比較できるようになります。

検証結果

モジュール 依存ライブラリ ビルド速度
RealmClient Realm 1.9s
SwiftDataClient SwiftData 2.6s

仮説②の通り、ビルド速度はほぼ同じになりました!!

感想

結果で見た通り、Realmもコンパイル済みのバイナリを扱うようにすれば、ビルド速度のボトルネックは大幅に解消できそうです。
今回の手順では、XCFrameworkをリポジトリに含める必要があるので、リポジトリのサイズが大きくなってしまう懸念がありますが(別の方法あったら教えてもらえると嬉しいです)
それでもビルド速度の面で受けるメリットはかなり大きいので、このアプローチでビルド速度解消できるケースも多そうと思いました。

ビルド速度だけみると、SwiftDataの方が圧倒的で驚きでした。多少早くなるだろうとはおもってたけど、まさかここまで差が出るとは思わなかったです。

ただ、ローカルストレージライブラリとしてのパフォーマンス面で比べると
大量のデータに対しての読み書きなどはRealmの方が上なので、
パフォーマンス重視のプロダクトにはRealmを使うといった判断はできそうですね。
パフォーマンスとビルド速度はトレードオフになりそうなので、そこを考慮して今後はローカルストレージのライブラリ選定をしたいです。

工夫すれば、Realm/SwiftDataに依存したプロジェクトのビルド速度はほぼ同じなので、
どちらを使うかを検討する時は、ライブラリの機能面やパフォーマンス面を重視する方が良さそうと思いました。





Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -