Your SlideShare is downloading. ×
Msを16倍出し抜くwpf開発1回目
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Msを16倍出し抜くwpf開発1回目

2,728
views

Published on

コアコンセプトテクノロジー山本礼貴さんの勉強会発表資料です。 …

コアコンセプトテクノロジー山本礼貴さんの勉強会発表資料です。
WPFのチューニングに関するノウハウで、まさに実践で苦労の末に獲得し、惜しげも無く公開。全4回のうちの第1部です。
今後も楽しみなセッションです。

Published in: Technology

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,728
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
10
Comments
0
Likes
5
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Microsoftを16倍出し抜く C#+WPF開発手法 第1回(1倍までの道) 山本礼貴
  • 2. 誰のためか  対象者  C#と.NET Frameworkに対する大まかな知識を持つ人  WPFに対する大まかな知識を持つ人  動機  WPFのプログラムの動作が遅いという懸念や不満
  • 3. 頂上までの道 WPFの根本的問 題を解決する (16倍~) WPF を制御する (4~16倍) WPFを効率的に使う (1~4倍) 誤った使い方をしないこと (~1倍)
  • 4. アジェンダ  高速化って何?  WPFの構造  流れと弱点と対策を知る  まとめと次回予告
  • 5. 高速化って何? 基礎が最初に必要です。4ページでおさらいします。
  • 6. 一般的手法 (今日は一部しか扱いま せんが)  正しいデータ構造(コレクションの特性を活かす)  求められるのは変更に対する強さなのか、検索に対する高速性 なのか、列挙の速度なのか、省メモリなのか。  効率的なアルゴリズム  データ構造に合わせた手法を選ぶ。  同じ処理を無駄に繰り返さないこと(遅延評価、イベント集約 等は重要なテクニック)。  チューニング  コードのほとんどはループ。ループを速くすれば速くなる。し ないループ(省略したループ)が最も早い。  短いコードは速いことが多い(LINQは例外)。  ボトルネックの発見と除去(ベンチマークは徹底的に)。  この色の部分はマイクロソフトが極めて重視してます。
  • 7. .NET Framework では (この部分も今日のネタ ではありませんが)  糖衣構文(シンタックスシュガー)の解釈に対する正しい理 解  メモリ転送量と演算量を把握すること。  ガーベージコレクションの動きを把握すること。  IL(中間コード)を確認しながらコードを書くこと。  いやそもそも、どんな機械語になるのか理解すること。
  • 8. WPFでは (構造を知ってないと、 一般的手法を役立てる場 所を見失います)  4つのパスを理解すること(時間軸の区分)  イベント処理とユーザーコード  バインディングパス  レイアウトパス  描画パス  情報の所在と関連を理解すること(メモリ空間軸の区分)  アンマネージ領域  OSに依存するリソース群  マネージ領域  クラスと構造体  ビジュアルツリーとロジカルツリー  依存関係プロパティ  描画命令バッファ(隠ぺいされている)  テクスチャ(隠ぺいされている)  デバイスのステート管理(隠ぺいされている) 今日のネタ 次回以降のネタ
  • 9. WPFは遅い?  「悪いパターン」が内在しています  パネルの基底クラスに無駄なソートが含まれています。  依存関係プロパティへのアクセスはMicrosoftが主張するほど速 くありません。(特にPropertyMetadataの種類に気を付けま しょう)  Microsoftが推奨しない使い方は設計通りの速度が出ません。  リッチゆえに遅い部分が存在します  実は、アンチエイリアスを解除するだけで5倍くらい高速にな ります。  Freezeするだけで速くなる部分があります。  構造を理解せずに使うと遅いところがあります  プロパティ変更から再描画に至るまでにパスを理解していない と、速くすることができません。  見えないコストを理解していないと、それ以前のすべての動作 と無関係に遅くなります。 本日の主なネタ
  • 10. WPFの構造 時間軸上の構造を知った上で、やってはいけないことを 理解しましょう。すべてはその後。
  • 11. WPFの骨格1 (概念) ユーザー コード • 入力やイベントの処理 • Model層の変更(データの更新) • ViewModel層への変更通知(表示層への伝達経路) データバイ ンディング • ViewModel層の変更をViewに伝達(表示の更新のための設定) • レイアウトパス用のフラグ設定(要サイズ測定、要配置・再描画) レイアウト パス • コントロールのサイズ測定 • コントロールの配置と描画内容の確定 描画パス • 最適な方法で描画を実施する(DirectXを内部で使用しています) MVVMという手法を用いても用いなくても、流れは同じです。
  • 12. WPFの骨格2 (実装) 具体的にどこに記述され るのか。 理想的にはこれを無駄な く循環させたい。 ユーザー コード • あらゆるユーザーコード • イベントハンドラ データバイ ンディング • XAMLで記述する部分と依存関係プロパティ • OnXXXXXChanged等 レイアウト パス • MeasureOverride • ArrangeOverride/OnRender 描画パス • 描画(要はここに速くたどり着きたいだけ)
  • 13. 流れと弱点と対策を 知る 入力から描画までを淀みなく扱うことで、Microsoftが想 定した速度を得ることができます。
  • 14. 知るべき 共通ルール (イベント集約とは) プロパティA変更→ イベント パスA パスB プロパティA変更→ イベント プロパティA 変更通知  同一パス内において、1変更に対して1イベントが発生しま す。  各パスの間において、変更箇所の集約がなされているため、 次のパスは1回しか動かないようになっています。  パスとパスの間は後続処理で非同期です。 例えば、Width/Heightを変更した際に、 2回のPropertyChangedイベントが発生します。 変更の都度イベントが生じます。 しかし、レイアウトパスでの処理は1回に集約されます。 このイベント集約を活用することができると、 本来の速度を獲得できます。 (1回)
  • 15. ユーザーコード × バインディング  依存関係プロパティを何回 変更してもバインディング 処理は1回です。  依存関係プロパティに書く 処理自体が重たいので要注 意(最小限の書き込み回数 を心がけてください)  Opacity(透過率)の設定 はコントロールに対して極 力行わないようにしましょ う。  可能な限りFreezeしましょ う。  バインディングはパスが違 うために非同期なので、要 注意です。 ユーザー コード • 入力やイベント の処理 • Model層の変更 • ViewModel層への 変更通知 データバ インディ ング • ViewModel層の変 更をViewに伝達 • レイアウトパス 用のフラグ設定 (要サイズ測定、 要配置・描画)
  • 16. バインディング × レイアウトパス  バインディング中に、依存 関係プロパティは変更され ます。  無限ループに陥らない範囲 でのプロパティ変更は自由 です(ただし、遅い)。  描画命令の蓄積 (OnRender)までがレイア ウト処理です。  レイアウトパスの中で、依 存関係プロパティの変更を すると、バインディングと レイアウトパスはやり直し です(初心者がはまる罠)。 データバ インディ ング • ViewModel層の変 更をViewに伝達 • レイアウトパス 用のフラグ設定 (要サイズ測定、 要配置・描画) レイアウ トパス • コントロールの サイズ測定 • コントロールの 配置と描画内容 の確定
  • 17. レイアウトパス × 描画パス  OnRenderが呼ばれた順序で 描画されるわけではありま せん。  通常はPanel.Zindexの順序 で描画されます。  内部的にはビジュアルツ リーの親子リレーション シップが構築された順序で 描画されます。  描画パスにはユーザーコー ドの介在余地はありません が、OnRenderの書き方と Opacityの設定が悪いと遅 くなります。 レイア ウトパ ス • コントロール のサイズ測定 • コントロール の配置と描画 内容の確定 描画パ ス • 最適な方法で 描画を実施す る(DirectXを 内部で使用し ています)
  • 18. WPFの急所 3選  全パネル内の最凶ボトルネックはPanel.ZIndexのソート  子要素が1つでも変わるとZIndexを工夫もなくソートしていま す。Childrenの着脱を最小限にする必要があります。  Canvas,Grid,StackPanel等、すべてのパネルはPanelを継承し、 Panelの機能をすべて使っています。  レイアウトパス(Measure/Arrange/OnRender)で依存関係プ ロパティ変更をすること  再バインディングが実施されて、レイアウトパスが何度も走り ます。  描画パスにおいてコントロールの透過率変更は極力回避。せ めてブラシの色の透過率を変えましょう。  透過率を実現するために、一時テクスチャを生成して描画する ことがあります。死ぬほど重いです。  そもそも透過率変更はDirect3D内部のFlush処理を呼ぶことが多 いので、描画の終了待ちが挟まれます。  次点:Freezeしていない描画要素  イベント乱れ打ち状態になる場合があります。
  • 19. まとめと 次回予告  まとめ(まず1倍の速度を得ます)  流れを乱さなければ設計通りの速度を得ることができます。  実際に遅いと言われる例は、前述のパスの振る舞いを無視してい るケースが圧倒的に多い。  急所に極力触れないようにすることが大切。  次回以降予告  ビジュアルツリーを理解しましょう。ビジュアルツリーを効率 的に再描画するアルゴリズムと実装方法。  Panel.ZIndexをどうやって解決するか。 MSDNにすら詳述されない(でもリファレンスコードを読めば はっきりと読み取れる)最速のパネルの作り方とは・・・。 MVVMでも旧方式でも効いてくる方法があります。
  • 20. ご清聴ありがとう ございました。 http://proprogrammer.hatenadiary.jp/ こちらもご覧ください。