てくメモ

trivial な notes

C#

【Godot C#】Cysharp の次世代 Rx ライブラリ「R3」を Godot で使ってみる

【追記】 この記事はR3のプレビューリリース時に書かれたものであり、正式リリース (2024/2/16) においては内容が符合しない部分があります。 Cysharp からプレビューリリースされた次世代 Rx ライブラリ、「R3」を Godot(ver. 4.2.1)で試す。 GitHub - Cy…

【C#】並列実行での数値カウント

C#

マルチスレッドの排他制御に関するある記事で、数値を操作するだけであってもInterlockedクラスよりlockステートメントの方がよい、と書かれていたのが感覚と異なったので、自分でも測ってみる。 単純なインクリメントを、Parallel.Forにより並列実行したベ…

【C#】スタック上に class インスタンスを錬成する

C#

以下のポストがきっかけ。 In .NET you can load a huge graph(s) of objects directly from a file and, basically, mmap it & register as a managed heap! GC won't waste time scanning/compacting/collecting it. Quick example of me registering stac…

【C#】長さを利用した CopyTo のJIT最適化を試す

C#

最初にきっかけとなったポストを示す。"why the _hacker version is faster?" ということなので、ポスト初見の場合、一度考えてもいいかもしれない。 Some JIT magic for you - both methods do the same work, why the _hacker version is faster? pic.twi…

【C#】ASCII文字に最適化された処理を提供する Ascii クラス(.NET 8~)

C#

.NET 8 から、ASCII文字に最適化された処理を提供するAsciiクラスが提供された。 Ascii クラス (System.Text) | Microsoft Learn Performance Improvements in .NET 8 - .NET Blog 文字列を扱う際、仕様上・あるいは事実上ASCII文字だけということは珍しくな…

【C#】分岐最適化時代の Compare の書き方

C#

※ 大仰なタイトルですが、下記記事の一部分を引き伸ばした内容になります。 Performance Improvements in .NET 8 - .NET Blog 上記記事の Branching の項目で、分岐レス化による最適化が解説されている。 詳細は元記事参照として、Compare 的な処理が例とし…

【C#】Span<byte>.SequenceEqual に代えて数値型で == する方法の確認

C#

下記スライドを学習した際、記事名の内容の効用が気になったので、マイクロベンチマークする。 CEDEC 2023 モダンハイパフォーマンスC# 2023 Edition - Speaker Deck byte列の照合を取る際は通常、SequenceEqualメソッドを用いる。比較するReadOnlySpan<byte>が静</byte>…

【C#】辞書の key への列挙型の利用

C#

enumを数値型にキャストして辞書の key にする、というコードを見たのをきっかけ。enumそのままとintにキャストした key で比較。 結論から言えば、単純な get/set のマイクロベンチマークでは有意な差はなかった。 レガシーな環境以外では実益はなさそう? …

【C#】2つの float が概ね等しいかを得る処理の確認

C#

実用のうえで、近似した2つの浮動小数点数(この記事ではfloat)を等価として扱いたい場合がある。 Console.WriteLine(0.2f * 0.1f == 0.02f); // False // ⇧ 実用のうえで、True として扱ってほしい 記事現在、標準ではその機能を直接提供するメソッドはな…

【C#】null許容型のイディオム

C#

null許容型(プロジェクト設定に応じてT?型または参照型)をパターンマッチングでさっと扱うコードを見て、まだ頭に馴染んでなかったと感じたので記事に書いて馴染ませる。 ついでにパターンマッチング以外も整理する。 null 条件演算子 (?. / ?[]) null 合…

【C#】デリゲートを取る引数に ラムダ式 / 各種メソッド / ローカル関数 を渡した際の違いを確認する

C#

自分の認識と少し状況が変わっているという話を見聞きし、まとめて確認。 ラムダ式、インスタンスメソッド、staticメソッド、拡張メソッド、ローカル関数を渡す メンバーやローカル変数をキャプチャしないのを前提 .NET 8 / C# 12 ケースをフォーカスしてし…

【C#】DefaultInterpolatedStringHandler を StringBuilder 的に使う

C#

本記事は、C# Advent Calendar 2023 12日目参加記事となっています。 11日目:【C#】抽象クラスとインターフェースを併用する理由を考えた by @seiya2130 13日目:ISpanFormattableを使おう by @Shaula C#において、複雑な文字列を組み立てる手段として挙げ…

【C#】FakeTimeProvider と FakeLogger を試す

C#

.NET 8 の目玉のひとつに時間抽象化があり、それを利用したFakeTimeProviderが提供された。 (.NET 8~) また、同様に Fake を冠するロガーとして、FakeLoggerが提供された。 (.NET 8~) FakeTimeProvider クラス (Microsoft.Extensions.Time.Testing) | Micr…

【C#】OrderBy(_ => Guid.NewGuid())

C#

.NET 8 で標準のシャッフルが用意されたということで、OrderBy(_ => Guid.NewGuid())との差を確認しておいてみる。 念のため触れておくと、OrderBy(_ => Guid.NewGuid())は、本来ソートに使うメソッドに本来Guidとして生成する数値を渡し、シャッフルとして…

【C#】.NET 8 で Random クラスに追加された Shuffle と GetItems の中身の確認

C#

.NET 8で追加されたRandom.ShuffleメソッドとRandom.GetItemsメソッドの中身を確認しておく。(.NET 8.0 リリース時点) 前者はシャッフル、後者は選択肢の中からランダムに選ぶ(よその名前では choice とか sample とか)もの。 なお、System.Security.Cry…

【C#】コレクション式 : 独自型でコレクション式を使ってみる (CollectionBuilder 属性)

C#

C# 12 で導入されたコレクション式は、CollectionBuilderAttributeを用いることで、独自型にも導入できる。 公式ドキュメント ・コレクション式 (コレクション リテラル) - C# | Microsoft Learn ・CollectionBuilderAttribute クラス (System.Runtime.Compi…

【C#】コレクション式 : ILを見てどういう中身か掴む(Span, ReadOnlySpan, 配列, List)

C#

C# 12 で導入されたコレクション式について、従来型の記述などとILを簡単に見比べておくもの。(.NET 8.0 リリース時点、ILSpy使用) コレクション式についての参考リンク ・コレクション式 (コレクション リテラル) - C# | Microsoft Learn ・コレクション…

【C#】文字列から<T>型への汎用コンバート : IParseble<TSelf>

C#

IParsable<TSelf>というインターフェースがある。(.NET 7~) https://learn.microsoft.com/ja-jp/dotnet/api/system.iparsable-1?view=net-8.0 実装している型は、ParseメソッドとTryParseメソッドを持つ。 例えば以下のように使える。 public T ConvertByIParsab</tself>…

【C#】SearchValues<char> を測ったら桁違いに速かった

C#

Youtubeの動画みたいな記事タイトル。でも実際速い。 SearchValues<T>は .NET 8 から入った効率的な検索用に最適化された型。 SearchValues.Createメソッドから生成したSearchValues<T> (.NET 8.0 現在、Tはchar/byte) を、Span<T>.IndexOfAnyメソッドなどに渡して用</t></t></t>…

【C#】ReadOnlySpan<T>最適化の確認

C#

以前、最適化によりbyte[], sbyte[]がゼロアロケーションとなる場合を確認した。 【C#】ゼロアロケーションバイト列 - てくメモ これについて、現在1は対象が拡大している。 参考 ・コレクション式 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C …

【C#】ジェネリック型引数の型の new()

C#

ジェネリック型引数の型のインスタンスを作成したいという場合がある。このときはまず、型制約のnew()制約が考えられる。 public interface IInterface { } public IInterface GenericNew<T>() where T : IInterface, new() { return new T(); } ただ、これは内</t>…

【C#】(int, int).GetHashCode の衝突

C#

以下の記事によれば、-1000~1000 の範囲で(int, int).GetHashCodeを検証したところ、98.3%衝突していたということ。 C#でDictionaryのキーに2つのintを使いたい場合の性能比較 (ただしキーの範囲は[-32768, 32767]) 数字が衝撃的なので、自分でも確認してみ…

【C#】算術のいくつかの最適化 tips を測ってみる

C#

アルゴリズムではない tips 的な算術の最適化、例えば、除算ではなく逆数を乗算する、のようなものが、どの程度効用があるのかを測って確かめてみる。なお、体系的なものではなくて、並べているだけ。 除算(逆数の乗算) 奇数偶数判断(ビット演算) 絶対値…

【C#】一次元配列を二次元に回転

C#

width と height のあるデータを一次元で扱っているとき、それを回転することを考える。なお、並べ替え先に外部領域を使う。また、記事名は配列としているが、記事内のコードはSpanとして扱っている。 参考イメージ画像。 0° 右回転 右90°行と列が入れ替わる…

【C#】文字列から<T>型への汎用コンバート

C#

【追記】 .NET 8 以降は、IParsable<T>インターフェースでこの記事の範囲のことを扱えます。 【C#】文字列から<T>型への汎用コンバート : IParseble<TSelf> - てくメモ 例えば文字列からのジェネリックな汎用コンバートを用意したいとする。このとき、手段としてTypeConv</tself></t></t>…

【C#】IEnumerable<T>.ToXXX 系の確認

C#

以下の記事で、IEnumerable<T>.ToArrayの中身を確認した。 【C#】IEnumerable<T>.ToArray の中身を確認 - てくメモこの機会に、それ以外のコレクションにするメソッド(ToList、ToDictionary、ToHashSet、ToLookup)を確認しておく。ちなみに、変わったことはなか</t></t>…

【C#】列挙せずに要素の数の取得を試みる IEnumerable<T>.TryGetNonEnumeratedCount

C#

IEnumerable<T>.TryGetNonEnumeratedCount(out int)メソッドは、列挙せずに要素の数の取得を試みることができる。(.NET 6 ~)とりあえず確認用のクラスを用意して、Count()と並べてみる。 // 確認用クラス private class SignalItem { public SignalItem Sign</t>…

【C#】IEnumerable<T>.ToArray の中身を確認

C#

IEnumerable<T>を列挙済みにしたり、あるいはコピーとして使ったりするToArray。 活躍の機会が多いだけに中身を確認しておく。 まず、IEnumerable<T>.ToArrayは拡張メソッドであり、Enumerable.ToArray<TSource>に定義されている 参考:Source Browser public static TSourc</tsource></t></t>…

【C#】Span.Overlaps を見る

C#

Span に拡張メソッドとして生えているOverlapsメソッドが気になったので、簡単に確認してみる。 MemoryExtensions.Overlaps メソッド (System) | Microsoft Learn このメソッドは、ある Span が別の Span とメモリ上で重なっているかを判定するもの。まず、…

【C#】null の Span

C#

連続したメモリ領域を表すSpan<T>は、nullを受けることもできる。 その場合、== nullで中身の参照のnullチェックができる。 int[]? array1 = null; int[]? array2 = new int[] { 1, 2, 3 }; ReadOnlySpan<int> span1 = array1; ReadOnlySpan<int> span2 = array2; Console</int></int></t>…