スキップしてメイン コンテンツに移動

投稿

[C#]ILSpyを使ってCILを見る

前回の記事でReSharperを使ってCILを見てみましたが、ReSharperを利用すると該当ファイルのCILしか見れず、アセンブリ情報などのCILは見れませんでした。
前回記事:[C#]ReSharperを使ってCILを見るそこで、ReSharper購入以前に使っていたILSpyを使って見ようと思ったらVisual Studio Extensionがあるのを今更発見したので紹介しておきます。インストールは簡単でVisual Studioのツールバーのツール=>拡張機能と更新プログラム=>オンラインからILSpyを検索して出てきたものをインストールするだけです。インストールできたらソリューションエクスプローラーのプロジェクトを右クリックするとILSpyで開く項目があるのでクリックしましょう。クリックしたらILSpyのWindowが開くのでCILを眺めることができます。と言ってもアセンブリで眺めたい情報ってあまりないかなという感じですね。.assembly SharedProperty.NETStandard { /*略*/ .hash algorithm 0x00008004 // SHA1 .ver 1:0:0:0 } .module SharedProperty.NETStandard.dll // MVID: {908E02B5-14DD-4164-8C84-C47735CD9DCA} .corflags 0x00000001 // ILOnly たとえば、SharedProperty.NETStandardはこんな感じのアセンブリ情報ですけど、見た目そのままの意味です。
.NET IL Assemblerという本には.assembly extern { auto }みたいな感じでバージョン自動解決なアセンブリインポート?というのができるみたいな感じに書いてありましたけどそういった記述は見つけることができず…
ILSpyでアセンブリのReferencesで参照アセンブリがコメントで書かれてるのでILSpyが自動判別してる…?(未確定情報)また、ILSpyなら名前空間の情報も見れます。(たいした情報ないですけど).namespace SharedProperty.NETStandard.Storage { …

[C#]ReSharperを使ってCILを見る

こないだセールで買ったReSharperですが、さっそくReSharperの機能をことごとくオフにしていってしましました。
(決してReSharperが重いということはない(建前)けど、VisualStudio標準のサジェストとかが優秀になってきたからそのあたりはわざわざReSharperじゃなくていいやということです)その中で、唯一ReSharperの強みがあってIL Viewerです。表示の仕方は簡単で、ツールバーのRESHARPERからTools => IL Codeと押すだけです。
最新のCILを反映させるにはビルドする必要があります。最初のコードusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SampleProject1 { class CilTest { private readonly string text = ""; public void Main() { Console.WriteLine("Hello CIL!"); } public string Text => string.Empty; } } 無駄にusingしてたりしますが、このコードのCILを眺めましょう.class private auto ansi beforefieldinit SampleProject1.CilTest extends [mscorlib]System.Object { .field private initonly string text .method public hidebysig instance void Main() cil managed { .maxstack 8 // [15 13 - 15 45] IL_0000: ldstr "Hello CIL!"…

Xamarin.iOSならExpressionよりリフレクションのほうが早いかもという話

元ネタはこちら: うさ☆うさ日記 - [C#]Xamarin.iOSでLambdaExpression.Compile()が通る件最初に断っておきますが結構雑なベンチマーク計測してますそこで、本題の件に入る前に技術的背景。C#でのメタプログラミングにはいろいろと方法があって、この話に関係するものでも3つあります。リフレクション Javaとかにもある奴で、型名とかメソッド名を取得したり実行できる、取得するのも実行するのもとても遅いIL Emit 動的にCILを生成することでプログラム実行中に処理を追加できたりする、生成はそれなりに遅いが、一度生成すれば実行するのは高速Expression IL EmitはCILをC#コードから生成することになるので普通の人にはできない、それを式木という形でC#っぽいコードでできるようにしたもの、これも一度生成すれば実行するのは高速※正確な表現にはなってないかもしれませんが、だいたいこんな感じです。そこで、問題のXamarin.iOSですが、iOSでは動的コード生成が許されてません(それぐらいいいじゃないかと思うかもしれませんが林檎の方針なので従うしかないです)。動的コード生成が許されないということは、動的にコードを生成してるIL Emitはできないということです。
これはMSのドキュメント: Xamarin.iOS の制限事項にも書かれていることです。ということで、IL Emitをしているパフォーマンス重視のライブラリーとかは軒並みXamarin.iOSでは利用できないことになりますが、同じような仕組みのExpressionを使っているライブラリーはなぜか動きます。はて、なぜ動くのだろう?と考えると式木でリフレクションっぽいことをするようにしてるんだろうなぁということは想像つきますね。問題のベンチマーク元ネタでは丁寧にベンチマークをとられていましたが、めんどくさいのでインスタンス生成だけ軽くどんなものか計測してみることにします。 public async void BenchmarkAsync() { string time = await timerAsync(); // Xamarin.FormsのLabel Text.Text…

ReSharper買いました

突然ですが、JetBrainsが半額セールをしてました。国際フレンドシップ・デー。世界中のプログラマーへJetBrainsからのプレゼント

期間限定でJetBrains IDEのパーソナルライセンスが50%OFF!https://t.co/Rt22HOt5WVpic.twitter.com/PDlD4wMEE8— JetBrains (@jetbrainsjp) 2018年7月30日前々から欲しかったReSharper(以下R#er)を買いました。自分はWindows環境なのでRiderを使うという選択肢はなく、簡単なサジェスト機能が欲しかったので、R#erのみのライセンスにしました。仕事でRiderを使ったことがあるのでR#erがどういう機能があるのかだいたい想像ついているところです。最近はVisual Studioも機械学習を取り入れて強くなってきてるところなので、R#erは買うに値する存在なのか、どこが強いのかなどをお伝え出来たらなと思っています(実際にするとは言っていない)。

[C#].NET Core 2.1でstring.StartsWithが遅くなることがある話

個人的にstring.StartsWith系統どれが一番早いの選手権開きたかったので、いろいろと計測していたのですが、どうも .NET Core 2.1だけ異常に遅い場合があるという発見をしたのでメモです。
計測したのはいつも通りBenchmarkDotNetです。
計測対象は以下のコード
private readonly string text = "text is big title"; [Benchmark] public bool StartsWithDefaultOfEqualText() { return text.StartsWith(text); } [Benchmark] public bool StartsWithOrdinalOfEqualText() { return text.StartsWith(text, StringComparison.Ordinal); } [Benchmark] public bool StartsWithDefault() { return text.StartsWith("text is big"); } [Benchmark] public bool StartsWithOrdinal() { return text.StartsWith("text is big", StringComparison.Ordinal); } カルチャー指定と、比較元と比較対象が同じ場合の4パターンです。
結果:
BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores Frequency=332812…

ブログテーマ変えました

気まぐれでブログテーマ変えました。以前から少し読みにくいなーと感じてたところなので、ちょうどいい機会だった感じです。デザインとかはBloggerのテーマのNotableをそれなりに改造したものです。レイアウト崩れとかあったらご連絡お願いしますm(__)m(テーマ変えてから1時間程スマホのレイアウトが崩れてましたごめんなさいm(__)m)

[C#]Xamarin.FormsのApplication.Current.Propertiesより高性能な設定保存ライブラリ作った話

タイトルは半分釣りです(ごめんなさい)
(半分大真面目)【告知】Xamarin.Formsのhttps://t.co/eC46vr1kqiを強くしたようなもの(自称)としてSharedPropertyを公開しました~
内部的にはUtf8JsonかSpanJsonを使うようにしてます。
.NET Standard 2.0で作ってるのでアプリケーションデータを保存する際にぜひ使ってくださいm(__)mhttps://t.co/VWeI7FDhSW— Kペンギン (@penguin_sharp) July 16, 2018作った動機もともと、こんなライブラリ作るつもりなんてなかったんですが、理想のMVVM Navigatorを製作中にXamarin.AndroidでのViewModelの状態保持がきついなと。どういうことかというと、AndroidではView(Activity, Fragment)間の画面遷移時のデータのやり取りはIntentまたはBundleクラスを経由するんですが、そいつらに渡せるデータはJavaで言うところのプリミティブ型であったりJavaのSerializableインターフェースを実装したものまたはAndroidのParcelableインターフェースを実装したもののみなんですよ。そんなインターフェースをMVVMのViewModelであったりModelに持ってこれるわけもなく、普段ならModelをJson化して文字列を画面遷移時に飛ばしていました。そういう標準的な仕組みを使わずにアプリケーションレイヤーでゴネゴネと頑張ってたわけですが、理想のMVVM Navigatorを作るとなると何らかの機構を用意しなければいけないと。また、他にも画面遷移以外にも画面回転でViewが一度死ぬことにも対応しないといけません。これは前述したBundleクラスでデータを保持することで対応できるのですが、同じくMVVMではきつい。.NET/Xamarin.Forms的にはそういうときはおとなしくViewModelが一度死んで、データは永続化して対応するという手法もあるようなので、それを参考にしようかなと。AndroidのSharedPreferencesは実装がいいとは言えない前述のわけで、データの永続化方面に着目していくわけですが、AndroidのSharedPrefer…