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

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

C#

Blazor の大部分がASP.NET Core 3.0 のプロジェクトに移動した

すぐにBlazorが使えるという意味ではありませんが、Razorが標準コンポーネントになるのは素直に嬉しいところです。 github.com 機械翻訳ですが、以下の通り BlazorとRazor Componentsプログラミングモデルのほとんどすべてのソースは、ASP.NETの中央コアリポ…

Blazor で PWAを作る

最近C#も良くなってきましたが、Web開発環境も良くなってきました。 いろいろなことができるのは良いことです。 今回はBlazor 0.7.0 で PWA(プログレッシブWebアプリ)を作ってみました。 Blazor 0.7.0 の環境構築はこちらのとおりです。 Blazor 0.7.0 experi…

Blazor を用いたスクリプトレスWebアプリ開発の可能性

Blazor0.6.0を用いたスクリプトレスWebアプリ開発の可能性 from Yamamoto Reki www.slideshare.net という勉強会を職場でやったので、スライドを共有します。 なお、ここに書かれていることは私見で、特定の団体や企業の考えを代表するものではありません。

Blazorを使ってみた(2)…再

役に立つ情報を書けていなかったので1つ前の記事は削除しました。 Blazorに取りつかれて毎晩少しずつコードを書いていると、どんどんコントロールの整理が進んでいきます。今のところ業務的なDBに対するCRUDを行なう画面を作ってもJavaScriptの記述量は0行と…

共用体でGuidすら速くできる

CEDEC2018の傍ら、こんなベンチマークを思いつきで書いていました。 まずは結果からご覧ください。Meanの値から、だいたいSystem.Guidよりも2倍は高速です。 Method Mean Error StdDev ImmutableGuid_In 20.83 us 0.1102 us 0.0977 us ImmutableGuid 22.46 …

C#7.3 in this ValueTuple が速い

C#7.3でこんなベンチマークをしました。 in this ValueTuple の組み合わせが出来ると本当に高速です。 [Benchmark] public void DoubleMaxLegacy() { for(int idx=0 ; idx<10000;idx++) result[idx] = Math.Max((double)(10000 - idx), (double)idx); } [Ben…

値型のデフォルトコンストラクタのコスト

C#における struct は引数が無いコンストラクタを書くことができないのですが、return new Size();こういうのはコスト0で戻り値に格納してくれるのだろうかという疑問について、調査しました。 極めて厳密に最適化をすると、このコンストラクタはインライン…

パフォーマンスが落ちていないことを確認する大切な作業

新しい糖衣構文が出てきたらILの品質を確認しましょう。 VisualStudio 2015のC#では以下のように同じようなプロパティを記述できます。 class Test{ int Value1{ get; set; } = 100; int _value2 = 100; int Value2 { get{ return _value2; } set{ _value2 =…

デリゲートの最適化にもう1歩踏み込む

デリゲートの最適化についてはもう1歩踏み込んでみたいと思います。 下記のようなコードをビルドしてみると /// <summary> /// string.IsNullOrWhiteSpace /// </summary> static Func<string, bool> stringIsNullOrWhiteSpace = string.IsNullOrWhiteSpace; static void Main(string[] args)</string,>…

delegate + ref が速いケース

foreachで12bytes程度以上の値型配列をループするより、delegateでref型を受ける形のループの方が速いのですね。具体的な根拠は Measure It ですが。 Measure It - Home明示的に delegate って書かないといけないところがちょっと苦しいですが。 ILコード的…

仮想化しないでも速いCanvasの作り方

XAML Advent Calendar 2014 - Qiita XAML Advent Calendar 2014 - Qiita こちら向けの記事です。1日遅刻しました。ごめんなさい。 あちこちで書いて回っておりますがPanel.Childrenがとても重いのです。 遅い原因はこちら。 http://referencesource.microsof…

FreezableにDataContextが伝播する仕掛け(その2)

素早く実証コードを書いてみました。 ViewModelとしては概ねこんな感じ using System; using System.Windows; using System.Windows.Input; using System.Diagnostics; namespace WpfApplication1 { class MainWindowViewModel : DependencyObject { public …

FreezableにDataContextが伝播する仕掛け(その1)

依存関係プロパティ(継承タイプ)を変更しますと。 このあたりをスタート地点としまして。http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/DependencyObject.cs,1243長い処理を経てここに到達します。http://referencesource.micro…

ベジェ曲線のHitTest

WPFにあまり任せてはいけないのがベジェ曲線のHitTestです。 几帳面で抜け目ありませんが、きわめて低速です。真面目に方程式を解く手法ももちろんあるのですが、実はあんまり工夫しないでも、そこそこに優良なコードは書けます。 概ねこんなノリです。動か…

MSを16倍出し抜くなんとか2回目

Msを16倍出し抜くwpf開発2回目 先日やった勉強会資料2回目です。 簡素な仮想化パネルの元資料です。

続・ハッシュコードをバラけさせる意味はあるのか

というわけで、.NET Frameworkのご本尊様を調べてみたのですが。http://referencesource.microsoft.com/#mscorlib/system/collections/generic/dictionary.cs,290このコードを見る限り、GetHashCode()は別にバラケさせる必要はありませんね。 コスト比皆無で…

イベント集約という手法

一長一短あります。 本日はイベント集約のこと。イベントは大変便利ですが、1つのイベントにどの程度のリスナーが居るかを正確に管理するのは大切です。WPFを手本にすると、バインディングパスとレイアウトパスに関して見事なイベント集約がなされているこ…

foreachのILとループのパターン

糖衣構文としてとても有名なforeachはおおまかに2種類のILになる可能性があります。 配列に対するIL(for文とほぼ同等) IEnumerable になる IL ループだけの速度では前者が約2倍速です。 IEnumerator が IDisposable なので IEnumerableは try - finally で…

簡素な仮想化パネル

こんなXAML <Window x:Class="Test.FastCanvas.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Test.FastCanvas" Title="MainWindow" Height="350" Width="525"> </window>

共変性と反変性のこと、無法なobjectを撤廃する事

C#に触れていると嫌でも出てくる共変性と反変性のこと。 これを合理的に扱えずに悩んだことはありますか? そんなあなたにC#的処方。あんまり、ここしばらくリファレンスコードのことばかり書いたので、少しは普通のコードを論理的に綺麗にまとめる手法を提…

RecomputeZState()を読みます

http://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Panel.cs#1001これはPanel.csの一部です。 ZIndexが変更されたり、Panelの子要素が追加される度にこれくらいの処理が行われることを覚えておきましょう…

VirtualizingStackPanelのコード長いですね

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

手遅れ SizeChanged

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

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なのですが…