地図利用はスマホがメインになっている。PCはC#、スマホはAndroid Javaであり、互換性はない。 スマホに重点を置くため、PCでは独自のパフォーマンス向上は狙わない。
PC地図画面の測定時のサイズは 800x500 とする。 レンダリングスレッド数はスマホと同じ8としている。 PCの物理コアは2つに過ぎないが、スレッド数=4より、スレッド数=8の方がいい結果が得られたので、 スマホのスレッド数に合わせた。
劇的に高速化した。これで、陸地ポリゴンのレンダリング&描画をひとまず完了として、次のステップに進む。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 53 28 38 28 29 26 19 21 19 12 10 14 11 13 9 22ms
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 86 72 98 59 59 59 46 32 36 42 36 37 47 39 43 53ms
画面描画に5msほどかかる。最後に1回、同じ描画を繰り返しているケースが多い。 スマホの場合、1タイル毎の描画ではない。全体として数回の onDraw であるが、 パソコンは1タイルのレンダリングが終わるごとに、OnPaint が実行され、 しかもスマホに比べて時間がかかるようである。
レンダリングが終わるごとに描画を実行せず、画面当たりの発行回数を3回程度に抑えてみよう。 OnPaint側で、この描画抑制を行うのがいいであろう。
地図ソース、センター座標 CX、CY が変わるごとに監視をリセットする。zoom の変更は CX、CYに反映される。 例えば、12枚のレンダリングが必要となった場合には、4タイル以上、8タイル以上、12タイルで描画を実行する。 0、1、2、3では描画はしない。次は、4とは限らず、5かもしれない。8、9かもしれない。 その場合には、ここで最初の描画を行い、次は全タイルのレンダリングが終わったときとなる。
全タイルの描画が終わったあとは、やはり、ソース、CX、CY が変わるまで、描画は行わない。
スクロール(ソース、zoomの変更はない)の場合は、最初の OnPaint で大半のタイルがキャッシュにある。不足タイルがあった場合、1タイル準備完了ごとに、描画する。
プログラムを書いて分かった。
最後に2度実行されるのは、画面クリアと描画が分かれているためのようである。 OnPaintで描画をスキップするのは面倒かもしれない。Refresh() の発行回数を抑える方が無難なようだ。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 79 96 100 83 87 72 57 48 40 45 44 40 47 50 53 63ms
面積の小さいものを除くなどまだまだ無駄を省く余地が残されている。
実行時間は 26%増加した。メモリ使用量の増加は予測していたが、実行時間の増加は予想外である。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 121 127 109 123 127 119 75 63 69 67 63 56 68 55 65 87ms
少し、見直し計測した。やはり、20%程度の増加となっている。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 123 126 127 98 143 99 69 56 63 51 63 60 50 60 57 83ms
OSM では float[] points にして、Renderingメソッドで PointF配列に変換した。 C# としては PointF 配列の方がプログラムは簡単になるが、 Android Javaの場合、OSMに常に Path を使うわけではないので、float[] points の方がいい。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 110 124 127 99 100 100 73 67 63 67 58 65 64 58 60 82ms
特に空間検索の無駄を減らした。修正前と同程度になった。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 108 102 101 109 101 66 57 54 40 44 51 47 47 55 44 68ms
特に zoom 8, 9 では小さくて描画されないポリゴンを minzoom で除外すべきであろう。 zoom 7以下についても、面積による絞り込みの妥当性をチェックすべきであろう。もっと除外できるものがあるかも知れない。
int[] tags, int[] multi も加えたが、陸地ポリゴンでは働かない・
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 110 101 100 119 100 76 48 44 45 43 39 60 56 49 46 69ms
画面全体のレンダリングと表示が終わるまでの時間(ms)を以下に示す。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 110 101 100 119 100 76 48 44 45 43 39 60 56 49 46 69ms
画面全体のレンダリングと表示が終わるまでの時間(ms)を以下に示す。
zoom 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 平均 time 91 91 99 118 92 82 71 77 71 61 60 50 82 64 67 78ms
zoom を変更した時点から、表示完了までの時間を計測した。 下に zoom 6, 7 の結果を示す。表示タイル数は平均的にスマホより多い。 最初の数値が小さいのは、1回目はレンダリングが終わったものは一切ないためであろう。 8タイルのレンダリングがほぼ一斉に始まり、次々、レンダリングが終わる。 2番目の数値が最速タイルのレンダリング&表示完了時間、3番目の数値が次のタイルの時間 となる。
以上、最初がごく小さく、次が大きく、その後は少しずつ遅れるのは納得のいく話である。
最終数値が、画面全体のレンダリング&表示時間となる。
スマホより速いが、何倍も速いというわけではない。
OSMParserやOSMDeviderの処理は大きなメモリを必要として、また、何分もかかる。 到底、スマホでは実行できないが、レンダリングや表示といった msないし数秒といった 処理はスマホでも十分速い。
zoom=6 0.8ms zoom=6 23.5ms zoom=6 27.1ms zoom=6 29.7ms zoom=6 31.8ms zoom=6 35.1ms zoom=6 39.4ms zoom=6 42.1ms zoom=6 46.3ms zoom=6 49.4ms zoom=6 57.1ms zoom=6 61.2ms zoom=6 65.6ms zoom=6 72.3ms zoom=6 76.4ms zoom=6 80.3ms zoom=6 86.9ms zoom=6 91.1ms zoom=6 94.5ms zoom=7 0.8ms zoom=7 10.3ms zoom=7 16.2ms zoom=7 18.9ms zoom=7 22.1ms zoom=7 24.6ms zoom=7 27.7ms zoom=7 31.8ms zoom=7 36.4ms zoom=7 39.1ms zoom=7 43.4ms zoom=7 49.2ms zoom=7 54.8ms zoom=7 59.2ms zoom=7 64.5ms zoom=7 70.2ms zoom=7 74.3ms zoom=7 79.9ms zoom=7 86.0ms