2010年3月4日木曜日

番外編 イメージをキャッシュする

今回は特に~回とナンバリングするほど大きくないので。

TimelineItemViewModelごとにImageButtonを持っていますが、
つぶやきが1000個あれば同じボタンのImageのインスタンスが1000個生成されてしまいます。
まぁ最近のPCのメモリ量や、Imageといっても所詮小さいアイコンであることを考えると
あまり問題ではないかもしれませんし、
パフォーマンス改善は問題になったときに、ちゃんとボトルネックを計測したうえで行え、という
格言?もあるので、まだやらない方がいいかもしれませんが、
今回のケースはさすがに無駄な感じがしますし、
もし本当に初心者の読者の人がこの連載を読んで
リソースは豪快に使っていいものと誤解されるとまずいので、やっておきます。

キャッシュの方法はいろいろあると思いますが、
今回はImageButton内部にキャッシュを持ちます。



 public class ImageButton {
  private readonly string _description;
  private readonly ICommand _command;
  private readonly BitmapImage _image;

  private static Dictionary<string, BitmapImage> _imageCache = new Dictionary<string, BitmapImage>();

  public ImageButton(string description, ICommand command, string imageFilePath) {
   _description = description;
   _command = command;

   //同じ画像のボタンがたくさん生成されるので
   //ファイルパスが同じならキャッシュを使う
   if (_imageCache.ContainsKey(imageFilePath)) {
    _image = _imageCache[imageFilePath];
   } else {
    _image = new BitmapImage();
    _image.BeginInit();
    _image.UriSource = new Uri(imageFilePath, UriKind.RelativeOrAbsolute);
    _image.EndInit();
    _imageCache.Add(imageFilePath, _image);
   }
  }



つくりは簡単で、辞書(Dictionary)に登録されていなければ新規に作り、
すでに登録されていればそれを使い回します。
なお、ImageButtonは『数』は多いものの『種類』は多くないので
キャッシュが際限なく増えることはないと思いますが、
種類が増え続けるようなところで使う場合は、古いキャッシュを消す仕組みが必要です。

0 件のコメント:

コメントを投稿