de:code 2018に参加してきましたのでその結果をまとめています。
内容の間違い、誤字脱字等はご了承ください。正確なところは、本家のサイトを参照いただければと思います。
タイトル等
タイトル
[AD19]日本の第一人者が語る! C# の現状と今後への展望 「.NET Core 2.x 時代の C#」
演者
岩永 信之さん(++C++;//未確認飛行 C)サイト管理者
日時
2018/05/22 13:00-13:50
去年のdecodeで話したこと
- C#は停滞期をすぎて、 次の10年・20年を戦える環境に生まれ変わる
C#7.xは小数点リリース
- 細かく、頻繁にリリースする方針としている。詳細については、後述する。
パフォーマンス
- パフォーマンスがC#に必要なのか?という話もあるが、生産性優先なC#のパフォーマンスを、生産性下げずに上げられれば、そのほうがいい。
今年話すこと
- C# は、次の10年、20年を戦える環境に生まれ変わった。
- 去年からの進捗
- 今年の話し
現在のリリース状況とスライド内の記述
-
既存機能
- .NET Core 2.0
- C# 7.0
- C# 7.2
-
最近リリースされた
- .NET Core 2.1
- C# 7.3
-
将来
- .NET Core future
- C#8.0
この1年の.NET Core
- どう見てもWindows用、Coreにいれるの?な感じの互換パック
- Windows Compatibility Pack
- パフォーマンス、.NET Core 2.0、2.1にするだけで数割高速に
- C# 7.X活用する、細かい最適化多々
- ランタイムに手を入れないと実現無理な新機能の作業開始
- C# のコンパイル上のトリックではなくて、.NETのコアに手を入れなければいけない機能についても、実装して来ている。
新規なら、.NET Coreがいいかな、感
新機能なら、まずは.NET Core
新機能については、まずは、.NET Coreに実装している状況となっている。
.NET Frameworkへの実装は、.NET Coreから.NET Frameworkへの移植という形となるため、以下のような問題がある。
- .NET Frameworkに移植されるまでに時間がかかる
- パフォーマンスについては、問題が出てくる。.NET Coreのほうが早いという状況がありえる
- .NET Frameworkはside by sideではないので、環境依存となる
Windows Compatibility Pack
- Windows依存の機能も実装されている。Windows以外のプラットフォームでもビルドは通るし、動作する機能もある。一部はWindows限定であり、APIが例外を起こす
- 実際の実装時には=Windowsと書いておけば、If分岐されて必要場所のみビルドされる。あちこちに記載する必要はあるが、#ifではないので、通常のif文のため、コンパイル引数を与え忘れていたのでビルド不可という状況は起こらない。
.NET Coreのほうがメインストリームに
今後は、.NET Coreの方がメインストリームとなる。
GUIでも、.NET Coreの恩恵(パフォーマンス向上、side by sideインストール)などがある。
1つ注意点としては、クロスプラットフォームだからといって、Windows以外でWPFが使えるというわけではない。その目的ならば、Xamarinとなる。
.NET Frameworkの退役
全機能がCoreに移った時がFrameworkの退役どき。
とはいえ、現行のシステムについては、
-
.NET Framework をやめたい、としても
- システムの利用者がいるかぎり、サポートは切れない。また、メインストリームから外れても、.NET Frameworkのサポートはちゃんと行なわれる
-
.NET Coreで動かせる、としても
- 無理に、移行する必要はない。スレッド周りの問題で、問題が起きる可能性が高い
.NET Frameworkから、.NET Coreへの移行について
.NET Frameworkから、.NET Coreについては、ターゲットフレームワークを変えるだけでビルドできる、という状態にしたい。
実際、WPFのGUIを.NET Coreに持ってきてテストする、ということはしているが、大体動く。
もちろん、動くからといっても、スレッドの挙動の違いとかではまる可能性あり。たとえば、パフォーマンスを上げるとロックのタイミングが上がって破壊的変更につながる、ということはあり得る。
.NET Core の実装改善
低レイヤを触れる部分を公開することで、アプリ中で全体的なパフォーマンスを上げる、という改善、など細かいレベルでの改善を積み重ねている
ソースコード記述の変更 (.NET Core 2.0)
範囲チェックの書き方の変更
配列の範囲チェックのコーディングを変更することで、5%10%早くなったという命令が出ている。
長い処理をメソッド化する
インライン化がかかるかからないかで速度に違いが出てくる。
JITコンパイラが特殊な対応を行う (.NET Core 2.1)
ボックス化に関する処理(HasFlagを書くと遅いというのは有名)について、内部的なコードを変更することで高速化する。
特定CPUの専用命令を直接書き出せるように (.NET Core future)
高速化を突き詰めていくと、直接CPUに対しての処理を埋め込まないと改善できない場合は結構でてくる。ただし、特定のCPUがサポートしているかを確認してその場合だけコードを記載することになる。
サポートは大変、書くのは大変。ということだが、Intel系だけでも高速化したい、という状況で使える。
C#だけでは改善できなかった機能 (.NET Core future)
- ジェネリックな型を属性として使えるようになる
- インタフェースのメソッドに、実装を持てるようになる ライブラリを作成・配布する人向けの機能
こんなことも根本的な変更が必要だった。理由としては、C# Exというバージョンを出すわけにはいかないので、そう簡単には改善することはできなかった。
スケジュール感
以前は、実装に時間が掛かっていたが、最近は小分け(4カ月間ごと)に実装するようにしている。リリースが早くなることで、待望の機能が実装されるのが早い方が良い。という判断である。
そのかわり、バグも多めになっている。細かいバグは、次のバージョンでの対応となるので、その間は、バグの回避策を取っていただくことになる。
リリース後バグ報告していただくと、次バージョンのプレビュー版では直っていたりもする。もちろん次のバージョン(2〜3カ月後)では直っている。
リリース後もバグがあるということはありえる。割と簡単に行えるコミュニティー貢献なので、バグ報告よろしくお願いします。その際は、実際にコードサンプルがあると対応が早いかもしれない。
自分(岩永さん)に報告してもらっても良い。
小分けの実装例
要素の名前推論、タプルの比較
ref戻り値、refローカル変数
読み取り専用参照
実際あったバグ
defaultリテラル (修正済み)
in引数
パフォーマンス
C#でもパフォーマンス向上は必要である。
一部をC++で、という考え方もあるが、たとえ生産性が高いC#という言語であっても、実際のシステムの処理が遅かったら台無し。例えば、一部だけC++に変更したとしても、それ以外のC#の処理の部分が遅かったら、せっかくC++で高速化した分が無駄になる。
文字列処理の高速化
その他
* ref戻り値
* ref構造体、安全なstackalloc
* stackalloc初期化子、カスタムfixed
* Span構造体
* Spanを前提にしたI/O
* オーバーロード解決の改善
* ジェネリック型制約の追加
UTF-8を前提にした文字列
インターネットで扱われている文字列はUTF-8だが、Windows上では、UTF16である状態を改善したい為の変更となる。
C#についてその他
マイナー/メジャー並行開発
C#は、マイナーバージョンの変更とメジャーバージョンを並行開発している。細かく出せるものは、7.X。じっくり実装したい機能は、8.0という区分け。
8.0プレビュー
少々インストールが面倒(次が出た時にはいったん消してから入れる必要がある、など)なので、その点は留意する。
実装される機能の例
- null許容参照型
- 参照型にもnull許容、非許容の区別を
- パターンマッチングの強化
- 演算子で一定の範囲を表す
- async stream
- awaitとyield returnの混在
- foreach await
まとめ
- 移植で手一杯フェーズがやっと完了
- リリースタイミングとしては、C#が4~5ヶ月に一度。.NET Coreが1年に1度程度。