ページ

2009年12月4日金曜日

メモリ対決:NSTableView+カスタムセル vs NSCollectionView

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

(前回)Cocoaの日々: Cocoaの日々: NSTableView にカスタムビューを表示する (8) NSCollectionView で選択状態を描画する

NSCollectionView が NSTableView の代替として、機能的には使えそうなことがわかってきた。メモリ消費の観点ではどうだろうか。前回のサンプルを使い両者におけるメモリ利用状況を Instruments を使って比較してみた。

※以下、Mac OS X 10.5.8 (PPC)、Xcode 3.1、PowerBook G4 (1.5GHz/1GB) で検証


サンプルアプリ


Instruments

Xcodeを含む開発キットにはメモリ利用状況を調べることができる Instruments というツールが標準でついている。



これを使うとメモリの利用状況をクラス(オブジェクト毎)にグラフィカルに見る事ができる。

Instruments は Xcode内から呼び出せて、開発中のプログラムを簡単に調べることができる。




このツールを使い、1,000件のアイテムを扱う場合の両者のメモリ利用状況を調べてみよう。


(1) NSTableView+カスタムセル

まず NSTableView+カスタムセルでの1,000件表示

#Net / Overall: 10,085 / 25,059


Overallは生成したオブジェクトの累計個数を表す。#Net は現在利用中のもの(だと思う)。上位20項目はこんな感じ。トップの CFString は詳しくみると、Foudation や AppKit、CoreGraphics などシステム側が使っているものがほとんどのようだ。


ちなみにこのプロジェクトで作成している Homepage は詳細を見るとこんな風になっている。




Net Bytes / Overall Bytes: 1MB (1,007,104) / 30MB (30,017,440)
総利用バイト数の降順に並び替えてみた。

こちらもトップの CFSet はシステムが使っているものがほとんど。

GeneralBlock は malloc などで確保されたもので、数字が単位を表しているものと思われる(8192=>8,192バイト)。様々な用途で使われているが、画像データなどもこのなかに含まれるようだ(NSImage自体のサイズは小さい)。




(2) NSCollentionView

さて,お次は NSCollectionView。起動時間は NSTableView よりもかなり遅い。

#Net / Overall: 69,261 / 866,581

#Netベースでカスタムセルの約7倍、Overallだとなんと約34倍。NSTableViewに対して相当のオブジェクトを生成する。特に 16バイトという小さなブロックの確保が多い。



Net Bytes / Overall Bytes: 33MB (33,227,168) / 338MB (329,430,144)

NetベースでNSTableViewの約33倍(!)、Overallで約 11倍。NSTableView+カスタムセル実装に対して、いかに NSCollectionView の方がメモリ消費が大きいのかがよくわかる。


トップの GeneralBlock-143360の内訳は NSBitmapImageRep によって確保されたメモリ。アイテムで使っている NSImageView 内で使っている NSBitmapImageRep が消費したものだろう。


他にも上位の GenralBlockは画像関連で使われているものが多かった。




というわけで今回のケースでは NSTableView+カスタムセルのメモリ消費の方が圧倒的に少なかった(NSCollectionViewが圧倒的に多かったとも言える)。


(3) NSTableView+カスタムセル(100万件チャレンジ)


おまけとして NSTableView で 100万件にチャレンジしてみた。さすがに起動に少し時間がかかるものの数秒で画面が出てきた。下は一番最後のデータまでスクロールしたもの。NSTableView はすごいかも。

ただし選択するとこの通り。

描画位置がずれてしまっている。100万件のオーダーになると座標値に誤差が出てくるようだ。

ちなみに NSCollectionView は 1万件にして実行したところ固まってしまった(数分かかっても起動しなかったので強制終了)。


まとめ

1,000件程度でもこれだけの差がついてしまった。NSCollectionView は大量データを表示するような用途には向いていないようだ。メモリ消費量が多めであることを考えると NSCollectionViewを使う場合は一度に表示するアイテム数の上限を決めて、あとはページをめくって切り替える形式が良いと思われる。一方、NSTableView はメモリ消費も比較的少なく、100万件のデータも難なく?表示できることもわかった。通常の利用ではあまり件数を気にする事無く使えそうだ。

メモリ消費量の観点から BlogAssistant では NSCollectionをやめて、NSTableViewを使うことにする。レイアウトはコーディングでやるしかないが、ちまちまやって行こう。