tmytのらくがき

個人の日記レベルです

ぶっちゃけPathって速いの?

XAML AC25日目のエントリです。

スケーラブルグラフィック

世の中にはPathでお絵かきするひと*1がいろいろいますが、スケーラブルグラフィックはPathのほかにもう一つあります。そう、TextBlockです。 TextBlockはOpenType Fontを使うことで3次ベジェ曲線を扱うことができるため、これはスケーラブルグラフィックと言えますね!

このように、PathとTextBlockという2種類のスケーラブルグラフィックを扱う方法があるXAMLですが、どちらのほうがパフォーマンスが高いのか気になりました。というわけで試してみました。

試してみます

まずは、今回試す画像を作ります。Illustratorで適当にかきました。

f:id:tmyt:20141225002216p:plain

追記:ソースはこれ

次にこれをフォントにしていきます。てきとうにFontforgeあたりでSVGを読み込んでフォントファイルに変換します。

f:id:tmyt:20141225002340p:plain

フォントができたら、アプリに取り込みます。Assetsあたりにファイルを追加して、TextBlockに設定します。

<TextBlock FontFamily="Assets/CustomFont.otf#CustomFont" Text="&#xAE00" />

プロジェクト内のフォントファイルは、ファイルパス#フォント名とすることで参照できます。アプリにフォントを含める場合はこんな感じに書くと使えます。

フォントが読み込まれて、アイコンが表示されるとこんな感じ。良さそうですね。

f:id:tmyt:20141225002453p:plain

次に同じものをPathにします。Pathにするのは簡単で、BlendでAIファイルを取り込みます。ぱっとみ同じ見た目ですね。

f:id:tmyt:20141225002623p:plain

それぞれUserControlに貼り付けます。これをボタンを押すとCanvasに10000個作るようなコードを書いて、実際にプロファイラで測定してみます。

void Button1_Click(object sender, ClickEventArgs e)
{
    for(var i = 0; i < 10000; ++i) canvas1.Add(new PathView());
}

void Button2_Click(object sender, ClickEventArgs e)
{
    for(var i = 0; i < 10000; ++i) canvas1.Add(new FontView());
}

プロファイリングは、VisualStudioのAnalyzeのPerformance and Diagnostics から起動します。

f:id:tmyt:20141225002828p:plain

起動できたら、XAML UI Performanceにチェックを入れてStartをクリックします。すると、普段VisualStudioでデバッグするときの様にアプリが起動します。アプリの裏側ではVisualStudioがアプリのパフォーマンスをずっと測定してくれています。

適度に実行したところで、普段通りデバッグを終了します。今回は各ボタンを3回ずつクリックしました。合計、30000回インスタンスが作成され、ビジュアルツリーに追加されています。

さて、結果ですがこのように表示されます。

f:id:tmyt:20141225003210p:plain

大きな塊が6つあります。最初にTextBlock、次にPathを試したため、前半3個がTextBlock版、後半3つがPath版のパフォーマンスになります。 こうしてみると、明らかにTextBlockを使った方が赤いバーがたくさん含まれています。ここで、赤いバーはレイアウトにかかった時間を表しています。

こうしてみると、明らかにTextBlockが遅いです。Textを表示することの方が多いのでPathの方が遅いのではと思っていましたがそんなことはなく全然Pathの方が速いです。

Pathよりフォントにした方が…とか書こうと思ってたらPathの方が速かったので書くことがなくなりました。フォントにする手間もかかるし、別に速度面のメリットもないし、しいてメリットをあげるならTextBlockと書くだけで使えるとかでしょうか。

結論

Pathでいい

おわりに

明日はXAML AC最終日です。明日はGrabacr07 せんせーがどえりゃーエントリを書いてくれるはずなので期待して待っています!!

*1:@Grabacr07