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

Weitere ähnliche Inhalte

Was ist angesagt?

20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
Genya Murakami
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
Kota Mizushima
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
Yoshifumi Kawai
 

Was ist angesagt? (20)

20150530 めとべや東京 Reactive Property + Livetで作るWPFアプリ
20150530 めとべや東京 Reactive Property + Livetで作るWPFアプリ20150530 めとべや東京 Reactive Property + Livetで作るWPFアプリ
20150530 めとべや東京 Reactive Property + Livetで作るWPFアプリ
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
FINAL FANTASY XVにおけるPhoton利用事例 - Photon運営事務局 GTMF 2018 OSAKA / TOKYO
FINAL FANTASY XVにおけるPhoton利用事例 - Photon運営事務局 GTMF 2018 OSAKA / TOKYOFINAL FANTASY XVにおけるPhoton利用事例 - Photon運営事務局 GTMF 2018 OSAKA / TOKYO
FINAL FANTASY XVにおけるPhoton利用事例 - Photon運営事務局 GTMF 2018 OSAKA / TOKYO
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
NextGen Server/Client Architecture - gRPC + Unity + C#
NextGen Server/Client Architecture - gRPC + Unity + C#NextGen Server/Client Architecture - gRPC + Unity + C#
NextGen Server/Client Architecture - gRPC + Unity + C#
 
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
MRU : Monobit Reliable UDP ~5G世代のモバイルゲームに最適な通信プロトコルを目指して~
 
メタプログラミングって何だろう
メタプログラミングって何だろうメタプログラミングって何だろう
メタプログラミングって何だろう
 
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
 
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
 
Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話Unityでオンラインゲーム作った話
Unityでオンラインゲーム作った話
 
MagicOnion入門
MagicOnion入門MagicOnion入門
MagicOnion入門
 
なぜなにリアルタイムレンダリング
なぜなにリアルタイムレンダリングなぜなにリアルタイムレンダリング
なぜなにリアルタイムレンダリング
 
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
 
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
 
オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫オンラインゲームの仕組みと工夫
オンラインゲームの仕組みと工夫
 
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
「黒騎士と白の魔王」gRPCによるHTTP/2 - API, Streamingの実践
 
Unityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTipsUnityでパフォーマンスの良いUIを作る為のTips
Unityでパフォーマンスの良いUIを作る為のTips
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介Unity開発で使える設計の話+Zenjectの紹介
Unity開発で使える設計の話+Zenjectの紹介
 

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

データ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみよう
データ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみようデータ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみよう
データ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみよう
Salesforce Developers Japan
 
災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)
災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)
災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)
OSgeo Japan
 

Ähnlich wie Msを16倍出し抜くwpf開発1回目 (6)

async/await不要論
async/await不要論async/await不要論
async/await不要論
 
アドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニングアドテク×Scala×パフォーマンスチューニング
アドテク×Scala×パフォーマンスチューニング
 
データ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみよう
データ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみようデータ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみよう
データ連携の新しいカタチ - 変更データキャプチャ/プラットフォームイベントを MuleSoft Anypoint Platform と組み合わせて試してみよう
 
災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)
災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)
災害監視無人機システムと 災害監視無人機システムとFOSS4Gとの関わり ((独)宇宙航空研究開発機構 都甲 様)
 
知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能
 
Extract and edit
Extract and editExtract and edit
Extract and edit
 

Mehr von cct-inc

141126 勉強会 xsdの活用
141126 勉強会 xsdの活用141126 勉強会 xsdの活用
141126 勉強会 xsdの活用
cct-inc
 

Mehr von cct-inc (10)

帰宅部はじめました エクストリーム帰宅のすすめ
帰宅部はじめました エクストリーム帰宅のすすめ帰宅部はじめました エクストリーム帰宅のすすめ
帰宅部はじめました エクストリーム帰宅のすすめ
 
勉強会 2015-02-04
勉強会 2015-02-04勉強会 2015-02-04
勉強会 2015-02-04
 
勉強会 2014-12-11 (spain)
勉強会 2014-12-11 (spain)勉強会 2014-12-11 (spain)
勉強会 2014-12-11 (spain)
 
レース観戦入門
レース観戦入門レース観戦入門
レース観戦入門
 
201411 141204212906-conversion-gate01
201411 141204212906-conversion-gate01201411 141204212906-conversion-gate01
201411 141204212906-conversion-gate01
 
141126 勉強会 xsdの活用
141126 勉強会 xsdの活用141126 勉強会 xsdの活用
141126 勉強会 xsdの活用
 
プログラマへ送る電子工作基礎の基礎
プログラマへ送る電子工作基礎の基礎プログラマへ送る電子工作基礎の基礎
プログラマへ送る電子工作基礎の基礎
 
OpenCVの入り口
OpenCVの入り口OpenCVの入り口
OpenCVの入り口
 
「社会」から考える ~社会学?のすすめ~
「社会」から考える~社会学?のすすめ~「社会」から考える~社会学?のすすめ~
「社会」から考える ~社会学?のすすめ~
 
Parser combinatorってなんなのさ
Parser combinatorってなんなのさParser combinatorってなんなのさ
Parser combinatorってなんなのさ
 

Kürzlich hochgeladen

Kürzlich hochgeladen (11)

Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 

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

  • 2. 誰のためか  対象者  C#と.NET Frameworkに対する大まかな知識を持つ人  WPFに対する大まかな知識を持つ人  動機  WPFのプログラムの動作が遅いという懸念や不満
  • 3. 頂上までの道 WPFの根本的問 題を解決する (16倍~) WPF を制御する (4~16倍) WPFを効率的に使う (1~4倍) 誤った使い方をしないこと (~1倍)
  • 4. アジェンダ  高速化って何?  WPFの構造  流れと弱点と対策を知る  まとめと次回予告
  • 6. 一般的手法 (今日は一部しか扱いま せんが)  正しいデータ構造(コレクションの特性を活かす)  求められるのは変更に対する強さなのか、検索に対する高速性 なのか、列挙の速度なのか、省メモリなのか。  効率的なアルゴリズム  データ構造に合わせた手法を選ぶ。  同じ処理を無駄に繰り返さないこと(遅延評価、イベント集約 等は重要なテクニック)。  チューニング  コードのほとんどはループ。ループを速くすれば速くなる。し ないループ(省略したループ)が最も早い。  短いコードは速いことが多い(LINQは例外)。  ボトルネックの発見と除去(ベンチマークは徹底的に)。  この色の部分はマイクロソフトが極めて重視してます。
  • 7. .NET Framework では (この部分も今日のネタ ではありませんが)  糖衣構文(シンタックスシュガー)の解釈に対する正しい理 解  メモリ転送量と演算量を把握すること。  ガーベージコレクションの動きを把握すること。  IL(中間コード)を確認しながらコードを書くこと。  いやそもそも、どんな機械語になるのか理解すること。
  • 8. WPFでは (構造を知ってないと、 一般的手法を役立てる場 所を見失います)  4つのパスを理解すること(時間軸の区分)  イベント処理とユーザーコード  バインディングパス  レイアウトパス  描画パス  情報の所在と関連を理解すること(メモリ空間軸の区分)  アンマネージ領域  OSに依存するリソース群  マネージ領域  クラスと構造体  ビジュアルツリーとロジカルツリー  依存関係プロパティ  描画命令バッファ(隠ぺいされている)  テクスチャ(隠ぺいされている)  デバイスのステート管理(隠ぺいされている) 今日のネタ 次回以降のネタ
  • 9. WPFは遅い?  「悪いパターン」が内在しています  パネルの基底クラスに無駄なソートが含まれています。  依存関係プロパティへのアクセスはMicrosoftが主張するほど速 くありません。(特にPropertyMetadataの種類に気を付けま しょう)  Microsoftが推奨しない使い方は設計通りの速度が出ません。  リッチゆえに遅い部分が存在します  実は、アンチエイリアスを解除するだけで5倍くらい高速にな ります。  Freezeするだけで速くなる部分があります。  構造を理解せずに使うと遅いところがあります  プロパティ変更から再描画に至るまでにパスを理解していない と、速くすることができません。  見えないコストを理解していないと、それ以前のすべての動作 と無関係に遅くなります。 本日の主なネタ
  • 11. WPFの骨格1 (概念) ユーザー コード • 入力やイベントの処理 • Model層の変更(データの更新) • ViewModel層への変更通知(表示層への伝達経路) データバイ ンディング • ViewModel層の変更をViewに伝達(表示の更新のための設定) • レイアウトパス用のフラグ設定(要サイズ測定、要配置・再描画) レイアウト パス • コントロールのサイズ測定 • コントロールの配置と描画内容の確定 描画パス • 最適な方法で描画を実施する(DirectXを内部で使用しています) MVVMという手法を用いても用いなくても、流れは同じです。
  • 12. WPFの骨格2 (実装) 具体的にどこに記述され るのか。 理想的にはこれを無駄な く循環させたい。 ユーザー コード • あらゆるユーザーコード • イベントハンドラ データバイ ンディング • XAMLで記述する部分と依存関係プロパティ • OnXXXXXChanged等 レイアウト パス • MeasureOverride • ArrangeOverride/OnRender 描画パス • 描画(要はここに速くたどり着きたいだけ)
  • 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でも旧方式でも効いてくる方法があります。