SwiftのDictionaryのvalueにArrayを指定して、appendしたときのパフォーマンスがすごく悪い件。

Swiftで、valueがArrayとなっているDictionaryに対して、そのvalueにappendしたときのパフォーマンスがとても悪かった。
...どういうことかというと、例えば、

という、keyはStringで、valueにIntの配列を持つscoresに対して、

といった感じで、処理を行っているコードがとても遅かった。

調べてみると、どうやら都度Copy on Writeを行っているかららしい。(Copy on Writeをしていたかどうかは確認していない)

stackoverflow - Dictionary in Swift with Mutable Array as value is performing very slow? How to optimize or construct properly?

で、リンク先にあるように書き換えて対応した。
Dictionaryのvalueを、removeValueでポップして、ポップしたvalueにappendして、再代入...と、やれば良いみたい。
removeValueでポップしてるから、変更しても、Copy on Writeは走らないってことなのかな。

結果、速度は、桁違いに早くなった。

実験したコードがあるので、貼ります。

コードの解説
Score構造体を、年月の文字列で、仕分けするのが目的のプログラムです。
(そもそも実際に現場で書いていたプログラムでは、Scoreは、Date型のプロパティを持っていて、"yyyyMM"の形式のString型に変換して仕分けしていました。今回は実験のため、最初からString型で年月を定義しています。)
UIButtonを置いて、タップしたら、startButtonTappedで検証開始していました。
で、case1は遅い方、case2が改善した早いコードです。

の部分は、丁寧に書くと、

と、なります。
データの数が数千個だけでも、結構違うぞ!

結果
俺の環境では、データ約13万件に対して、
case1のコードで、約24秒
case2のコードで、約0.15秒
でした。
100倍違う!はんぱねぇ!