リフレクションよりも高速: Microsoft が C 用ソース ジェネレーターをプレビュー

Table of Contents

リフレクションよりも高速: Microsoft が C# 用ソース ジェネレーターをプレビュー

Microsoft は、ソース ジェネレーターと呼ばれる新しい C# コンパイラ機能をプレビューしています。この機能は、プロジェクトをビルドするときに、新しいソース コードを自動的に出力してコンパイルするとのことです。

この機能は最新の.NET 5.0プレビューに含まれています。.NET 5.0は、Windows専用の.NET Frameworkとクロスプラットフォームの.NET Coreを統合することを目的とした次期リリースです。別の見方をすれば、.NET Coreを拡張して.NET Frameworkの代替として使用できるということです。

プログラムマネージャーのフィリップ・カーター氏による発表では、この新機能について簡潔に説明されています。「ソースジェネレーターは、コンパイル時に実行されるコードの一部で、プログラムを検査して、残りのコードと一緒にコンパイルされる追加ファイルを生成します。」

問題は、なぜなのかということです。

ソースジェネレータは、コンパイルプロセスの一部として生成されたコードを追加します。

ソースジェネレータは、コンパイルプロセスの一部として生成されたコードを追加します。

カーター氏によると、主な当面の価値は、.NETのランタイムリフレクションと呼ばれる機能の代替となることです。ランタイムリフレクションにより、.NETコードは実行時にアセンブリ(コンパイル済みコードの単位)を分析し、型やオブジェクトを検出し、プロパティを読み取り、メソッドを呼び出すことができます。「例えば、ASP.NET CoreはWebサービスの初回実行時にリフレクションを使用して定義済みの構成要素を検出し、コントローラーやRazorページなどを「接続」できるようにします」とカーター氏は述べています。

リフレクションには時間がかかるため、ソースジェネレーターはコンパイル中にこれらのタスクを実行することでパフォーマンスを向上させる可能性があります。JSONや正規表現用の.NETパーサーなど、一般的に使用される多くのライブラリもリフレクションを多用しています。リフレクションの使用を減らすことで、AOT(事前コンパイル)コンパイルの最適化が向上するとCarter氏は述べています。

ソースジェネレーターは、コンパイル前にコードを生成するマクロと似ていますか?「重要な違いは、ソースジェネレーターではユーザーコードを書き換えることができないことです」とカーター氏は付け加え、この質問やその他の重要な質問に答えました。

いくつかの問題点がありますが、最大の問題は、これが現在C#のみの機能であるということです。Microsoftは「Visual Basicを言語として進化させる予定はない」と述べているため、Visual Basicに導入される可能性は低いでしょう。

F# への対応はフィードバック次第で、未対応になる可能性もあります。つまり、VB や F# をサポートしたいライブラリやフレームワークの開発者は、ソースジェネレーターを使わずに開発するか、リフレクションをフォールバックとして使い、同じコードを2回記述する必要があるということです。

混乱に拍車をかけたのは、ソース ジェネレーターは「技術的には C# 言語の機能ではない」が、C# 9.0 では (すべて順調に) 導入される予定である、と Carter 氏が述べたことです。

Source Generator が提供する可能性について詳しく知りたい場合は、さまざまなシナリオのサンプル コードが含まれている Source Generator Cookbook から始めるのがよいでしょう。

.NETの進化を追っている方は、チームによる新しいドキュメント「.Netランタイムフォームファクター」もぜひご覧ください。Microsoft .NET CoreアーキテクトのJan Kotas氏とプリンシパルプログラムマネージャーのRichard Lander氏は、.NET 5.0のロードマップを示し、Microsoftがこれまでに行った妥協点について説明しました。「私たちは、まずRedhawkプロジェクト、次に.NET Native、そして最後にオープンソースのCoreRTプロジェクトとして、.NETランタイム全体のクリーンな再設計を目指しました」と彼らは述べています。「これにより、C++やGolangなどの静的にコンパイルされた環境と同等のパフォーマンス特性を持つ.NETランタイムフォームファクターを構築できることがわかりました。」CoreRTは、.NETをネイティブコンパイル向けに最適化するための実験的なプロジェクトです。

残念ながら、近い将来にこれが実現する可能性は低いようです。当初の意図は「既存の.NETランタイム実装を完全に置き換える」ことでしたが、「この目標は非現実的であることが判明しました」と彼らは述べています。「この取り組みを実行するには、主流の.NETランタイムへの投資を極端に減速させる必要があります…私たちはそのような方向性は受け入れられないと考えています。」

代わりに、MicrosoftはCoreRTの一部を.NET Coreと.NET 5.0に復活させ、パフォーマンスを向上させていますが、当初のCoreRTプロジェクトが約束したほどではありません。もしお時間があれば、その影響についてはこちらで詳しく議論されていますので、ぜひご覧ください。これは、Kotas氏とLander氏が述べたように、「顧客が目に見える価値」のために、Microsoftが.NETの夢の一部を諦めたことを意味します。®

Discover More