ページ

2009年12月9日水曜日

NSTableView にカスタムビューを表示する (10) カスタムセル+CoreData のメモリ利用状況

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: Cocoaの日々: NSTableView にカスタムビューを表示する (9) カスタムセルでCoreDataを扱う

前回作成した NSTableView + カスタムセル + CoreData のメモリ利用状況を調べてみた。
※以下、Mac OS X v10.5.8、XCode3.1、PowerBook G4 (PowerPC 1.5GHz/1GB)で調査

Instruments

以前作った NSArrayベース(オンメモリ)での1000件での状況と比較してみる。
(なお結果は使っている環境や状況によって変わる。1、2回しか試していないので厳密では無いことに注意)

NSArrayベースの実装

# Overall: 25,059
# Net: 10,085
Overall Bytes: 約30MB  (30,017,440)
Net Bytes: 約1MB (1,007,104)


CoreDataを使った実装

ストレージタイプは SQLite で 1000件のデータはあらかじめ用意しておく。

結果:
# Overall: 28,291
# Net: 13,975
Overall Bytes: 約68MB  (6,851,024)
Net Bytes: 約1.3MB (1,325,760)


メモリは総利用量(Overall Bytes)としては約2倍と大きいが、Net Bytes はほぼ変わらない。CoreData 初期処理やデータフェッチなどで当初はメモリを消費するが、データを取り込んだ後はあまり食わないということか。意外だったのはオブジェクトの数(#Overall/#Net)がそれほど変わらなかったこと。
今回の結果だけ見ると CoreData によるオーバーヘッドは大きなものではないようだ。


なお NSArrayベースの実装ではデータをオンメモリ生成しているので(つまりファイルからの読み込み処理が無い)その分を考慮すると差はもっと縮まる可能性が高い。




グラフ:
# Overall でソート


Overall Bytesでソート




SQLiteのログ

ストレージタイプは SQLiteを使用している。クエリの発行状況も見てみた。

(参考)Cocoa Touch の日々: CoreData で発行されている SQL をデバッグ出力する


CustomCellWithCoredata[7681:10b] CoreData: annotation: Connecting to sqlite database file at "/Users/hashi/Library/Application Support/CustomCellWithCoredata/CustomCellWithCoredata.db"
CustomCellWithCoredata[7681:10b] CoreData: sql: pragma cache_size=1000
CustomCellWithCoredata[7681:10b] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
2009-12-09 08:15:41.158 CustomCellWithCoredata[7681:10b] CoreData: sql: SELECT COUNT(*) FROM ZHOMEPAGE t0 
CustomCellWithCoredata[7681:10b] CoreData: annotation: total count request execution time: 0.0043s for count of 1000.
CustomCellWithCoredata[7681:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZIMAGE, t0.ZTITLE FROM ZHOMEPAGE t0 
CustomCellWithCoredata[7681:10b] CoreData: annotation: sql connection fetch time: 0.0056s
CustomCellWithCoredata[7681:10b] CoreData: annotation: total fetch execution time: 0.0424s for 1000 rows.



最初に全件取得しているのがわかる。その後 NSTableView をスクロールしてもクエリは飛ばない。一気読みなのでメモリが十分にあれば早い。



100万件チャレンジ

お約束の(?)100万件にチャレンジ。




問題なく起動した。ただし並び順は番号順にならなかった。
CoreData(SQLite)は結構いける。

表示する時のSQLiteのログはこんな感じ。






CustomCellWithCoredata[8020:10b] CoreData: annotation: Connecting to sqlite database file at "/Users/hashi/Library/Application Support/CustomCellWithCoredata/CustomCellWithCoredata.db"
CustomCellWithCoredata[8020:10b] CoreData: sql: pragma cache_size=1000
CustomCellWithCoredata[8020:10b] CoreData: sql: SELECT Z_VERSION, Z_UUID, Z_PLIST FROM Z_METADATA
CustomCellWithCoredata[8020:10b] CoreData: sql: SELECT COUNT(*) FROM ZHOMEPAGE t0 
CustomCellWithCoredata[8020:10b] CoreData: annotation: total count request execution time: 26.5127s for count of 1000000.
CustomCellWithCoredata[8020:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZIMAGE, t0.ZTITLE FROM ZHOMEPAGE t0 




CustomCellWithCoredata[8020:10b] CoreData: annotation: sql connection fetch time: 7.2098s
CustomCellWithCoredata[8020:10b] CoreData: annotation: total fetch execution time: 32.3640s for 1000000 rows.
CustomCellWithCoredata[8020:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZIMAGE, t0.ZTITLE FROM ZHOMEPAGE t0 




CustomCellWithCoredata[8020:10b] CoreData: annotation: sql connection fetch time: 8.0894s
CustomCellWithCoredata[8020:10b] CoreData: annotation: total fetch execution time: 29.9665s for 1000000 rows.





さすがに起動に時間がかかる。全1,000,000件を最初に読み込んでいるようだ(しかも2回も)。
大量のデータを扱う場合は必要な時だけ読み込む(フェッチする)様になっているといいのだが。うーむ。

ちなみにデータ作成は 10,000件毎にコミット(save)する方法で5分程度かかった。



まとめ

今回のような単純なアプリケーションでは NSArray ベースのデータ管理に比べて CoreDataベースの管理のメモリ消費量は多いものの、極端に差は出ないことがわかった。このことから永続化を前提としたデータ管理を行う場合であれば、プログラミングが容易なCoreDataの方がずっと便利で役に立つことがわかる。


(12/11追記)Mac OS X v10.6 でも確認したところ、初回全件フェッチの挙動は変わらなかった。