パフォーマンス改善

お、おそい…

Amazonカート整理アプリもそろそろまがりなりにも使える形になってきたので、試しに自分のアカウントで使ってみた。

結果。おそい…

試しに、400個くらいある今は買わないのアイテムをショッピングカートの方に移動してみた。そしたらGUIの表示が
全然更新されない。かたまってしまう。

これは予想外。

まとめて移動させてみた

ソースを見直してみたら、二つのNSArrayControllerの間でデータを移動するにに、一つずつ動かしているのに気付いた。
まとめて動かすようにしたら改善するかもしれない。

    from_list = @cart.active_items
    to_list = @cart.saved_items
    to_list.addObjects(from_list.selectedObjects)
    from_list.removeObjectsAtArrangedObjectIndexes(from_list.selectionIndexes)

こんな感じ

***move 421 items...
took 12.4783091545105 sec

おお、終了しなかった時にくらべれば大分マシだ。

NSImageViewのimageURLをやめた

今まで表紙画像はNSImageViewのimageURLにURLをbindさせてたのだけど、ひょっとしたら
移動の度にこれが毎回作りなおされて遅くなっているのかもしれない、と思って試しに
NSImageを作って直接imageの方にbindしてみた。

  image_path = "/images/I/41R5gj5VRFL._SL110_.jpg"
  response = Net::HTTP.start("ec3.images-amazon.com").get(image_path)
  data = OSX::NSData.dataWithRubyString(response.body)
  cover_image = OSX::NSImage.alloc.initWithData(data)

こんな感じ。実際に既にDataがある場合は流用するようにしている。

***move 421 items...
took 0.708032846450806 sec

これでよし。

この結果は実験用にテキトーに書き換えた状態での値。ちゃんと使えるようにするには
かなりリファクタリングしなければならない。

そうはいっても、方向性が見えてまずは一安心。

追記

遅くなってたのは、二つのリスト間でアイテムを移動するときに、addObjectとremoveObjectで一個ずつやってたのが原因。
removeObjectは毎回配列をスキャンするので、配列の長さNに対して一つのアイテムを移動させる処理がO(N)になってしまう。配列全体を移動させるならO(N^2)だ。それは遅い訳だ。