qgmap の画像読み込みや拡大処理を高速化したい。
スタイラスで地図をグリグリやってると、画像読み込みのタイミングで、カクッ、カクッと引っかかるような感じがする。できれば PC で Google Map を使ったときみたいになめらかにしたいなぁと。特に拡大補完する場合は体感でわかるくらい重くなるので、拡大処理も見直したい。
ということで、画像読み込みや拡大処理の時間を測ってみた。
Google Map の画像は 256×256 の 8bit パレットの PNG 画像となっている。少しだけ 4bit, 2bit, 1bit PNG も混じっているみたいだけど。
今の qgmap では、QPixmap::load() を使って画像を読み込んで、拡大時は QPixmap::xForm() で拡大している。この xForm() は、QMatrix というクラスで座標変換の行列を設定して変換するんだけど、行列の係数はもちろん浮動小数点で指定するので、ここがすごく重そうな感じ。
とりあえず、QPixmap::load() と、QPixmap::xForm() の時間を測ってみる。
Qtには QTime という時間関係のクラスがあり、これで簡単にある区間の時間が測れるらしい。便利じゃのう。
QTime t; t.start(); 測りたい処理 printf("%dms\n", t.elapsed());
こんな感じ。printf 使うあたりが C++ に染まれていない証拠。
適当に測って平均するとこんな感じになった。
- QPixmap::load() 70.0ms
- QPixmap::xForm() 2倍拡大 (128×128→256×256) 122.1ms
- QPixmap::xForm() 4倍拡大 (64×64→256×256) 69.4ms
- QPixmap::xForm() 8倍拡大 (32×32→256×256) 50.3ms
- QPixmap::xForm() 16倍拡大 (16×16→256×256) 36.2ms
拡大処理は拡大元の面積に比例するようだ。思ってたよりも遅いなぁ。
ついでに、QImage::load() と、QPixmap::convertFromImage() の時間も測ってみた。
- QImage::load() 22.5ms
- QPixmap::convertFromImage() 58.5ms
Qimage::load() は PNGのデコード、convertFromImage() でスクリーンの32bppへ変換とローテーションをしてるのかな。両方合わせて QPixmap::load() よりちょっと長いくらいか。
これくらいなら、拡大する時は、QImage::load() → 独自拡大処理 → QPixmap::convertFromImage() の方が速そうだ。拡大しない時は QPixmap::load() で直接ロードで。
それにしても画像1枚読むだけで 0.1 秒近くかかってるんだな。縦方向にスクロールさせると最大4枚同時にロードするから、0.4秒以上止まっちゃうわけで。そりゃ引っかかる感じがするわけだ。根本的にはスレッド化してバックグラウンドでロードしないと解決しなそうだ。