C#+WPFチューニング戦記

C#とWPFで高速なコードと最適なシステムを書くためにやってきたいろいろな事を書いてみます。.NET Frameworkのソースコードを読み解きましょう。なお、ここに書かれているのは個人の見解であって何らかの団体や企業の見解を代表するものではありません。

2014-08-01から1ヶ月間の記事一覧

透過率の変更コストをご存知ですか?

DrawingContextに対する描画では、いろいろコストを考えなければいけないところがあります。 例えば、下記のコードは同じような描画を期待できそうですが、速いのはどちらでしょうか。こちらは、同じTransformのものをまとめています。 DrawingContext dc; f…

Z順序の問題とCanvasの関係について

見たまま記述からはてな書式に切り替えてみました。 考えてみたらこっちのほうがWikiっぽくて使いやすいし軽快ですね。 なんか書くのに時間がかかると思っていたら、それは編集用のパネルが遅いからだった、というわけです。 テキストボックスが遅いとか、や…

VirtualizingStackPanelのコード長いですね

ここのところ毎日ソースコードを読みながら実況中継という気分ですが。1日あたり1クラス程度を読むのを日課にしておりますが、本日は苦戦中です。 PanelがベースになっているVirtualizingPanelを基底クラスに持ちながら、VirtualizingStackPanelあの量の機能…

手遅れ SizeChanged

SizeChangedのイベントは、ちょっと届くのが遅いと思います。 本当の本当に、レイアウトパスも済んだところで届きます。うっかりこのタイミングで他のコントロールのサイズを上書きしてしまうと、またレイアウトパスが走ります。最悪、バインディングパスも…

短いコードを速くする努力とは

まずは短く。次いで速く。そんなお話。このブログにも実証コードはそのうち掲載していきたいところですが、当分はMicrosoftのリファレンスソースコードにリンクする事を主体としようと考えています。多くの現場で経験してきた事ですが、使っているものに対す…

UIElementやFrameworkElementの派生クラスのサイズ

UIElementやFrameworkElementや他のコントロール群。それらのサイズを決めるものは何でしょうか。 WidthやHeightはサイズを決めるものではなく、コントロールの使用者がどのようなサイズを期待しているか、標準の測定ロジック(すなわちMeasure)に知らせる…

85000バイト問題はいまだ健在

ガーベージコレクション(GC)のジェネレーションのことを調べたことはあるでしょうか。 .NET FrameworkのGCは現在3つのジェネレーションがあります。 極めて短期的なオブジェクトを扱うジェネレーション0 ある程度の期間に渡って保持されたオブジェクトのジ…

値型に対する拡張メソッドは、値型のサイズを検討してから

PointとSizeとRectとVectorは業務がら大変高頻度で使うのですが、小さい構造体ながら彼らのIsNaNが馬鹿にならないほど圧迫してきます。とはいっても、10分起動して6億回程度・・・・。 double.IsNaNはRect使用時に2~4回程度、ちょっとした矩形の合成でもや…

半端にLINQを使う悪手の代表例

古式なC#ですと、ループして、条件を絞り込む書き方が一般的でした。 // 例:1 foreach( var item in Items ) { if( item.Value > 10.0 ) { // 何かの処理 } } いやぁ、懐かしい。 LINQの登場(というか、メソッドチェインとラムダ式の導入)によって書き方…

enumはenum以外の用途で使うと遅いのは何故か

enumは糖衣構文です。実態はclass Enumです。 このEnumはenumの本分を尽くす限りにおいては高速です。 しかし、C/C++におけるenumとは根本的に異なっており、int等へのキャストは高速なのに、GetHashCode等のクリティカルなシーンにおいて非常に低速な実装を…

DependencyPropertyの急所を見つける

WPFに触れたことのある人ならバインディングの便利さを知らぬ人は居ないでしょう。これはその骨にあたる部分の話です。 DependencyObjectを継承したクラスにはDependencyPropertyを使用することができます。これは通常の依存関係プロパティとしてでなく、添…

Panel.Chidrenのボトルネックについて

Canvasにせよ、Gridにせよ、みんなPanel継承しています。 ですから、Childrenに子コントロールを追加していくことになります。ChildrenはUIElementCollectionです。UIElementCollectionの中身を知っておくことは重要です。中身はVisualCollectionなのですが…

IEnumerableを扱う諸々について

IEnumerable<TSource> を返すメソッドだからといって、こんなことをしていると凄い遅いコードが出力されます。 yield return new TSource(); yield return new TSource(); yield return new TSource(); プログラムの大半はループで構成されているのですから、ループが</tsource>…

Canvas.LeftやCanvas.Topの動作について

パネルのうちで極めて自由度が高いといえばCanvasですが、使い込めば使い込むほど中身のことをしっかりと理解しておく必要を感じるはずです。 http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Canvas.c…

callとcallvirtの違いとstructとinterfaceの関係

List<T>の話は具体的なILの話に続いていきます。 ILに変換された後にcallであるかcallvirtであるか、という違いは案外大きいようです。 callである場合、現時点の .NET Frameworkは比較的積極的な最適化を行ってくれます。一方callvirtになる場合の最適化は消極</t>…

List<T>の話

困ったことにList<T>を最近使いたくありません。 List<T>の場合.NET Framework 4.5 時点でいまだに for と foreach では、 forが高速に組めます。 コンパイラやJITの最適化が進化すれば同じ速度になるかと思いきや、いつまで経っても foreachの方が遅いのです。 あ</t></t>…

常識とかセオリーには何度もだまされたのです

最後にブログを書いていたころのことを思い出すと、あれからずいぶん技術的な点では変化があったなと思います。あの当時は.NET FrameworkにLINQなんてありませんでしたし、DirectXと相互運用できるOSSもありませんでした。WPFもありませんでした。 ただ、C#…