SlideShare a Scribd company logo
1 of 41
C# 7.2
with .NET Core 2.1
岩永 信之
今日の話
• .NET Core 2.xでのパフォーマンス改善の話
• C# 7.x
• .NET Core 2.xのパフォーマンス改善の流れに同調
• 去年リリースされたけど、.NET Core 2.1が出てからが本番
.NET Core 2.1
• https://blogs.msdn.microsoft.com/dotnet/2018/02/27/announci
ng-net-core-2-1-preview-1/
• Global Tools
• Build Performance Improvements
• Minor-Version Roll-forward
• Sockets Performance and HTTP Managed Handler
• Span<T>, Memory<T> and friends ←今日の話これ
• Windows Compatibility Pack
C# 7.2
• http://ufcpp.net/study/csharp/cheatsheet/ap_ver7_2/
• 数字区切り
• 非末尾名前付き引数
• private protected
• ref readonly/ref拡張メソッド/ref演算子
• ref構造体/Span<T>対応 ←今日の話これ
前振り:
C#/.NETのパフォーマンス
ベンチマーク
• 英語で「language benchmark」とかでググると…
• こんな感じの
サイトが
ベンチマーク(注意点)
• 英語で「language benchmark」とかでググると…
• https://benchmarksgame.alioth.debian.org/
• 注意点
• 言語をまたいだベンチマークは、言語の差だけじゃなくて
「どのくらい本気の人が参加してるか」による
• 実際、C#はちょっと前までいまいちなコードでだいぶ遅かった
• レギュレーション難しい
• C++は環境依存な関数を容赦なく使ってたりすることが
ベンチマーク(現状)
おおむね
C, C++ > Rust > Java, Swift, C#, Go > 関数型言語 >>> スクリプト言語
横並び
ベンチマーク(現状からいえること)
C#は…
.NET Core 2.0でちょっと速くなった
• C, C++基準で2~3倍遅い
• ここを縮めたいという要望は昔から多い
• 特定CPU向け最適化
• GC対策
• スクリプト言語基準で3~5倍速い
• にもかかわらず「Node.jsと比べてそんなに速くない」と思われてる
• 文字列処理の速度が大差ない
• 言語的な差よりも、内部のHTTP処理とかの方がネックになったりする
要するに、こんな要望になる
特定CPU向け最適化
Web高速化
GC削減
UTF-8
Hardware Intrinsics
参照と構造体活用
Span<T>
バイナリ処理
C# 7.0, 7.1
.NET Core 2.1以降
.NET Core 2.1
ということで今日のテーマ
• Span<T> (.NET Core 2.1)
• Hardware Intrinsics (.NET Core 2.1より後)
• おまけ: .NET Core 2.0での細かい最適化
• Span<T> (.NET Core 2.1)
• Hardware Intrinsics (.NET Core 2.1より後)
• おまけ: .NET Core 2.0での細かい最適化 軽い方から先に
例えばこんなリファクタリング(1)
• uint比較
• 効果
• 比較が1回減る
• 1命令と言えど、ループで頻繁に呼ばれる処理なので塵も積もる
if ((uint)x < length)
元 後
if (0 < x && x < length)
例えばこんなリファクタリング(2)
• Common Path Optimization (よく通る場所だけ優先最適化)
• 効果
• よく通る場所だけはインライン化が効いて速くなる
• (長かったり、throw文があるとインライン化されない)
if (9割方true)
短い処理
else
長い処理をメソッド抽出();
if (9割方true)
短い処理
else
長い処理
元 後
Q & A (1)
• Q. 「この手の細かい改善で5%くらい速くなります」といわれ
て、やる?
• A. 5%でもやりたい人という人は「世の中にはいる」
• こういうものは、限られた人数では最適化されづらい
• コミュニティ貢献が多いらしい
• ほんと細かい積み重ねはオープンソース強い
Q & A (2)
• Q. いまさら?
• A 1. .NET Frameworkからの移行で手一杯だったから…
• A 2. ほんと、いまさら
• 前述のとおり、こういうのはコミュニティ貢献が結構大きい
• 「いまさら」というなら、オープン化のタイミングが…
• 方針転換
• 最適化はコンパイラーの仕事ではないか → ホットパスは手作業してでも高速化
• Span<T> (.NET Core 2.1)
• Hardware Intrinsics (.NET Core 2.1より後)
• おまけ: .NET Core 2.0での細かい最適化
2.1から外れ
ちゃったんで…
おまけ程度に
C# 対 C言語
• 遅いのはガベージ コレクション(GC)?
• → No
• スタックの方が速いけどC#でもスタックを主体にしたコードは書ける
• そのための機能も年々増えてる(C# 7の構造体活用)
• 根本的に(Cでも)ヒープが必要なら、むしろGCは無茶苦茶速い
• じゃあ、あと、何が遅いのか?
• → 特定CPU向け最適化(CPU専用命令)
• 一番犠牲にしてるのはポータビリティ
• 要するに、速くしたければ#ifdefだらけ
CPU専用命令の例
• 例: SIMD
• single instruction multiple data
• Vector命令とか言われたり
• 例えばSSE(Pentium IIIの頃に導入された原始的なやつ)ですら
• 128ビットレジスターを持ってて
• float×4の四則演算を1命令でできる
• 単純に考えて個別に4回計算する場合の4倍速い
• オーバーヘッドの分を差し引いても倍は速い
単一 命令で 複数 データ を一気に処理
Hardware Instrinsics
• 専用命令の使い方
• 普通のコードを書いて、コンパイラーの最適化に任せる?
• 案外、その手のコードを生成してくれない
• コンパイラーが特殊な関数を用意
• 「この関数呼び出しは、この命令に置き換える」みたいなコンパイルを行う
#include <immintrin.h>
__m128 c = _mm_mul_ps(a, b)
コンパイラーによって
提供されるライブラリ
CPU専用命令に置き換わる
Hardware Instrinsics
• 専用命令の使い方
• 普通のコードを書いて、コンパイラーの最適化に任せる?
• 案外、その手のコードを生成してくれない
• コンパイラーが特殊な関数を用意
• 「この関数呼び出しは、この命令に置き換える」みたいなコンパイルを行う
#include <immintrin.h>
__m128 c = _mm_mul_ps(a, b)
こういう関数のことをintrinsicsという
• Intrinsic: 内在的な
• Hardware Intrinsics: 特定のCPUが内在的に
持っている機能
C#でHardware Intrinsics (1)
• パッケージ参照
• .NET Core 2.1 preview 1までは、標準に組み込まれる予定だった
• 2.1リリースには間に合わず、現状は
• パッケージ参照が必要
• 2.1リリース時点では「プレビュー」なパッケージになる予定
C#でHardware Intrinsics (2)
• コードの書き方
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
result = Sse.Multiply(Sse.Shuffle(a, a, 0x00), Sse.LoadVector128(p
result = Sse.Add(result, Sse.Multiply(Sse.Shuffle(a, a, 0x55), Sse
result = Sse.Add(result, Sse.Multiply(Sse.Shuffle(a, a, 0xaa), Sse
result = Sse.Add(result, Sse.Multiply(Sse.Shuffle(a, a, 0xff), Sse
・・・
命令セットの
名前のクラス
命令に対応
するメソッド
もちろんCPU依存…
• 当然、C言語だと#ifだらけになる
• C#でもifだらけになる
if (Sse.IsSupported)
{
return SseAdd(a, b);
}
else
{
return Add(a, b);
}
この命令セットを使える環境の時だけtrue
JIT時定数(falseの側は最適化で完全に消える)
使える場合と使えない場合の
2つの実装が必要
かなり速くできるけど、
「ifだらけ」「2重実装」
の覚悟が必要
デモ
• 行列の積和でベンチマーク
• SIMD命令を使うか使わないかでどのくらい速度差が出るか
• https://github.com/ufcpp/UfcppSample/tree/master/Demo/2018/Span
Performance/MatrixBenchmark
• Span<T> (.NET Core 2.1)
• Hardware Intrinsics (.NET Core 2.1より後)
• おまけ: .NET Core 2.0での細かい最適化
本題。
というか今日の話題で2.1
の話題なのはこれだけに
C#対スクリプト言語
• ベンチマーク上は3~5倍は速いはずなのに
• Webサーバーとして使うとなんかそこまで差がつかない?
• 3~5倍速いのは主に数値計算とか
• 文字列処理の速度が大差ない
• 言語的な差よりも、内部のHTTP処理(C#やスクリプト言語ではなく、
ネイティブで書かれてる)とかの方がネックになったりする
• WebがUTF-8で、C#のstringがUTF-16なのが問題に
Webでの文字列処理の例
• 例えばこんな感じのHTTP GETをしたとして
• (アップローダーからJSONをダウンロード)
• idとnameの値だけを取り出そうとしたとき… ちなみに、こういうJSON
文字列処理の現状
• Stream + stringでの処理
… 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D …
7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D
Stream.Read(byte[] buffer, int offset, int count)
Encoding.GetString(byte[] bytes)
… 22 00 69 00 64 00 22 00 3A 00 20 00 31 00 2C 00 0D 00 0A 00 20 00 20 00 22 00 6E 00 61 00 6D 00 65 00 22 00 3A 00 20 00 …
string.Substring string.Substring
31 00
1
22 00 3D D8 66 DC 3C D8 FD DF 22 00
"👦🏽"
UTF-8
UTF-16
文字列処理をどうしたいか(1)
• Nativeヒープを直接参照
… 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D …
IPipeReader.TryRead(out ReadResult result)
OwnedBuffer
参照管理のための小さいクラス
文字列処理をどうしたいか(2)
• UTF-8のままで処理
… 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D …
OwnedBuffer Utf8String
new Utf8String(buffer.Span)
文字列処理をどうしたいか(3)
• 部分参照でコピーを作らない
… 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D …
OwnedBuffer Utf8String
new Utf8String(buffer.Span)
Substring
Utf8String
Utf8String
1 "👦🏽"
スタックしか使わない
Substringもコピーを作らない
直接intにParse
すればヒープ不要
ToString時に
初めてヒープ確保
何が必要か
• メモリの一部分を参照
• Nativeヒープを直接
• stringの一部分
• 参照を前提にしたI/O
• UTF-8を直接読み書き
Span<T>型
Pipelines
Utf8String
.NET Core 2.1
その後
依存関係
C# 7.0~7.2
• ref戻り値
• ref安全ルール
Span<T>型
Pipelines
Utf8String
今ここ
Span<T>: 「範囲」を参照
• 論理的には、参照+長さ
… 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D …
1
struct Span<T>
{
ref T Pointer;
int Length;
}
どこから
何要素
例 ここから1バイト ここから10バイト
" "
Span<T>: いろんなところ参照
• Managedヒープも、Nativeヒープも、スタックも参照できる
Span<byte> span = new byte[N];
Span<byte> span = stackalloc byte[N];
var p = Marshal.AllocHGlobal(N);
Span<byte> span = new Span<byte>((byte*)p, N);
普通の配列 = Managedヒープ
stackalloc = スタック
P/Invokeやunsafe = Nativeヒープ
同じ型で参照できる
= 同じロジックで扱える
C# 7.2: Span安全ルール
• スタック(ローカル変数)の参照を外に返してはいけない
ref int Ok(ref int x)
{
return ref x;
}
ref int Ng()
{
int x;
return ref x;
}
Span<int> Ok(Span<int> x)
{
return x;
}
Span<int> Ng()
{
Span<int> x = stackalloc int[1];
return x;
}
ref安全ルール(C# 7.0) Span<T>※安全ルール(C# 7.2)
ローカル変数
(メソッドを抜けると消える)
消えるものの参照
(返そうとするとエラー)
※ 正確にはSpan<T>専用ではなくて、ref構造体に対して掛かる制限
C# 7.2: 安全なstackalloc
• 例: 頻出数字の検索
static int MostFrequentDigit(string s)
{
var digits = new int[10];
foreach (var c in s)
{
var d = c - '0';
if ((uint)d < 10) ++digits[d];
}
var max = 0;
for (int i = 1; i < 10; i++)
if (digits[max] < digits[i]) max = i;
return max;
}
0~9の文字の頻度をカウント
するための一時バッファー
配列のせいでヒープ確保
(あんまり好ましくない)
C# 7.2: 安全なstackalloc
• 例: 頻出数字の検索
static int MostFrequentDigit(string s)
{
Span<int> digits = stackalloc int[10];
foreach (var c in s)
{
var d = c - '0';
if ((uint)d < 10) ++digits[d];
}
var max = 0;
for (int i = 1; i < 10; i++)
if (digits[max] < digits[i]) max = i;
return max;
}
一時バッファーをnewから
stackallocに変更
ヒープ確保がなくなる
(速い)
unsafe不要
実際、安全
• 範囲チェックあり
• 外に返せないルールあり
デモ
• Substring
• ヒープ確保をなくせば無条件に速くなるというものでもない
• GCはほんとに速い
• Span<T>があるとだいぶ速い
• https://github.com/ufcpp/UfcppSample/tree/master/Demo/2018/Span
Performance/SubstringBenchmark
デモ
• Split → Join
• string.Splitやstring.Joinは一時的なオブジェクトを確保しまくる
• Span<T>でヒープ確保なくSplit, Join
• (ただし、使い勝手はあまり良くない)
• https://github.com/ufcpp/UfcppSample/tree/master/Demo/2018/Span
Performance/StringManipulation
まとめ
• 2.0~2.1、細かい最適化だらけ
• 2.0で実際あったのをちょっと紹介
• Hardware Intrinsics
• 2.1から外れちゃったけど
• 2.1時点で、プレビュー公開
• Span/UTF-8
• GC速いけど、「ヒープなし」にはさすがに敵わない
• そのためのref、Span<T>
• C# 7.2で関連機能すでに入ってる/.NET Core 2.1からが本番

More Related Content

What's hot

Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3信之 岩永
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方信之 岩永
 
知って得するC#
知って得するC#知って得するC#
知って得するC#Shota Baba
 
C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版信之 岩永
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesShintarou Okada
 
基礎からのCode Contracts
基礎からのCode Contracts基礎からのCode Contracts
基礎からのCode ContractsYoshifumi Kawai
 
動的なILの生成と編集
動的なILの生成と編集動的なILの生成と編集
動的なILの生成と編集terurou
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発Kazunori Hamamoto
 
Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Yuto Takei
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方Yoshifumi Kawai
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと信之 岩永
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話Kinuko Yasuda
 
プログラミング .NET Framework 第4版
プログラミング .NET Framework 第4版プログラミング .NET Framework 第4版
プログラミング .NET Framework 第4版信之 岩永
 
SEH on mingw32
SEH on mingw32SEH on mingw32
SEH on mingw32kikairoya
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 

What's hot (20)

Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
 
Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3Orange Cube 自社フレームワーク 2015/3
Orange Cube 自社フレームワーク 2015/3
 
C#言語機能の作り方
C#言語機能の作り方C#言語機能の作り方
C#言語機能の作り方
 
知って得するC#
知って得するC#知って得するC#
知って得するC#
 
C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版C#/.NETがやっていること 第二版
C#/.NETがやっていること 第二版
 
最速C# 7.x
最速C# 7.x最速C# 7.x
最速C# 7.x
 
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core GuidelinesBoost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
Boost.勉強会#19東京 Effective Modern C++とC++ Core Guidelines
 
基礎からのCode Contracts
基礎からのCode Contracts基礎からのCode Contracts
基礎からのCode Contracts
 
動的なILの生成と編集
動的なILの生成と編集動的なILの生成と編集
動的なILの生成と編集
 
Sharing Deep Dive
Sharing Deep DiveSharing Deep Dive
Sharing Deep Dive
 
今からでも遅くないC#開発
今からでも遅くないC#開発今からでも遅くないC#開発
今からでも遅くないC#開発
 
Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方Observable Everywhere  - Rxの原則とUniRxにみるデータソースの見つけ方
Observable Everywhere - Rxの原則とUniRxにみるデータソースの見つけ方
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 
C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話C++でCプリプロセッサを作ったり速くしたりしたお話
C++でCプリプロセッサを作ったり速くしたりしたお話
 
プログラミング .NET Framework 第4版
プログラミング .NET Framework 第4版プログラミング .NET Framework 第4版
プログラミング .NET Framework 第4版
 
SEH on mingw32
SEH on mingw32SEH on mingw32
SEH on mingw32
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 

Similar to C# 7.2 with .NET Core 2.1

リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010Tsukasa Oi
 
PSoCまつり「PSoCの美味しい料理法」
PSoCまつり「PSoCの美味しい料理法」PSoCまつり「PSoCの美味しい料理法」
PSoCまつり「PSoCの美味しい料理法」betaEncoder
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, CodereadingHiro Yoshioka
 
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」de:code 2017
 
分散メモリ環境におけるシェルスクリプトの高速化手法の提案
分散メモリ環境におけるシェルスクリプトの高速化手法の提案分散メモリ環境におけるシェルスクリプトの高速化手法の提案
分散メモリ環境におけるシェルスクリプトの高速化手法の提案Keisuke Umeno
 
Hokkaido.cap#1 Wiresharkの使い方(基礎編)
Hokkaido.cap#1 Wiresharkの使い方(基礎編)Hokkaido.cap#1 Wiresharkの使い方(基礎編)
Hokkaido.cap#1 Wiresharkの使い方(基礎編)Panda Yamaki
 
Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊
Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊
Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊Supership株式会社
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめMakiko Konoshima
 
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7Tetsuya Morimoto
 
ゆるふわLinux-HA 〜PostgreSQL編〜
ゆるふわLinux-HA 〜PostgreSQL編〜ゆるふわLinux-HA 〜PostgreSQL編〜
ゆるふわLinux-HA 〜PostgreSQL編〜Taro Matsuzawa
 
170622 02
170622 02170622 02
170622 02openrtm
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputingNoboru Irieda
 
Gpgpu tomoaki-fp16
Gpgpu tomoaki-fp16Gpgpu tomoaki-fp16
Gpgpu tomoaki-fp16tomoaki0705
 
ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!Yohei Fushii
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLakirahiguchi
 
201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト
201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト
201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキストVxRail ChampionClub
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 

Similar to C# 7.2 with .NET Core 2.1 (20)

リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
 
PSoCまつり「PSoCの美味しい料理法」
PSoCまつり「PSoCの美味しい料理法」PSoCまつり「PSoCの美味しい料理法」
PSoCまつり「PSoCの美味しい料理法」
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, Codereading
 
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
[TL06] 日本の第一人者が C# の現状と今後を徹底解説! 「この素晴らしい C# に祝福を!」
 
分散メモリ環境におけるシェルスクリプトの高速化手法の提案
分散メモリ環境におけるシェルスクリプトの高速化手法の提案分散メモリ環境におけるシェルスクリプトの高速化手法の提案
分散メモリ環境におけるシェルスクリプトの高速化手法の提案
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
Hokkaido.cap#1 Wiresharkの使い方(基礎編)
Hokkaido.cap#1 Wiresharkの使い方(基礎編)Hokkaido.cap#1 Wiresharkの使い方(基礎編)
Hokkaido.cap#1 Wiresharkの使い方(基礎編)
 
Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊
Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊
Graviton2プロセッサの性能特性と適用箇所/Supership株式会社 中野 豊
 
2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ2011.09.18 v7から始めるunix まとめ
2011.09.18 v7から始めるunix まとめ
 
エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7エキ Py 読書会02 2010/9/7
エキ Py 読書会02 2010/9/7
 
ゆるふわLinux-HA 〜PostgreSQL編〜
ゆるふわLinux-HA 〜PostgreSQL編〜ゆるふわLinux-HA 〜PostgreSQL編〜
ゆるふわLinux-HA 〜PostgreSQL編〜
 
170622 02
170622 02170622 02
170622 02
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
Gpgpu tomoaki-fp16
Gpgpu tomoaki-fp16Gpgpu tomoaki-fp16
Gpgpu tomoaki-fp16
 
ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
 
201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト
201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト
201711 vxrailチャンピオンクラブ_ワークショップ~入門編~テキスト
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 

More from 信之 岩永

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話信之 岩永
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話信之 岩永
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理信之 岩永
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型信之 岩永
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6信之 岩永
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に信之 岩永
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform信之 岩永
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略信之 岩永
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014信之 岩永
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎信之 岩永
 
Anders Hejlsberg Q & A
Anders Hejlsberg Q & AAnders Hejlsberg Q & A
Anders Hejlsberg Q & A信之 岩永
 
C#マスコット(公開用)
C#マスコット(公開用)C#マスコット(公開用)
C#マスコット(公開用)信之 岩永
 

More from 信之 岩永 (18)

YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話YouTube ライブ配信するようになった話
YouTube ライブ配信するようになった話
 
C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話C# コンパイラーの書き換え作業の話
C# コンパイラーの書き換え作業の話
 
Unicode文字列処理
Unicode文字列処理Unicode文字列処理
Unicode文字列処理
 
C# 8.0 null許容参照型
C# 8.0 null許容参照型C# 8.0 null許容参照型
C# 8.0 null許容参照型
 
Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6Unityで使える C# 6.0~と .NET 4.6
Unityで使える C# 6.0~と .NET 4.6
 
それっぽく、適当に
それっぽく、適当にそれっぽく、適当に
それっぽく、適当に
 
Modern .NET
Modern .NETModern .NET
Modern .NET
 
.NET Compiler Platform
.NET Compiler Platform.NET Compiler Platform
.NET Compiler Platform
 
Code Contracts in .NET 4
Code Contracts in .NET 4Code Contracts in .NET 4
Code Contracts in .NET 4
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略今から始める、Windows 10&新.NETへの移行戦略
今から始める、Windows 10&新.NETへの移行戦略
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014
 
.NET vNext
.NET vNext.NET vNext
.NET vNext
 
Coding Interview
Coding InterviewCoding Interview
Coding Interview
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
Anders Hejlsberg Q & A
Anders Hejlsberg Q & AAnders Hejlsberg Q & A
Anders Hejlsberg Q & A
 
C#マスコット(公開用)
C#マスコット(公開用)C#マスコット(公開用)
C#マスコット(公開用)
 
広がる .Net
広がる .Net広がる .Net
広がる .Net
 

C# 7.2 with .NET Core 2.1

  • 1. C# 7.2 with .NET Core 2.1 岩永 信之
  • 2. 今日の話 • .NET Core 2.xでのパフォーマンス改善の話 • C# 7.x • .NET Core 2.xのパフォーマンス改善の流れに同調 • 去年リリースされたけど、.NET Core 2.1が出てからが本番
  • 3. .NET Core 2.1 • https://blogs.msdn.microsoft.com/dotnet/2018/02/27/announci ng-net-core-2-1-preview-1/ • Global Tools • Build Performance Improvements • Minor-Version Roll-forward • Sockets Performance and HTTP Managed Handler • Span<T>, Memory<T> and friends ←今日の話これ • Windows Compatibility Pack
  • 4. C# 7.2 • http://ufcpp.net/study/csharp/cheatsheet/ap_ver7_2/ • 数字区切り • 非末尾名前付き引数 • private protected • ref readonly/ref拡張メソッド/ref演算子 • ref構造体/Span<T>対応 ←今日の話これ
  • 7. ベンチマーク(注意点) • 英語で「language benchmark」とかでググると… • https://benchmarksgame.alioth.debian.org/ • 注意点 • 言語をまたいだベンチマークは、言語の差だけじゃなくて 「どのくらい本気の人が参加してるか」による • 実際、C#はちょっと前までいまいちなコードでだいぶ遅かった • レギュレーション難しい • C++は環境依存な関数を容赦なく使ってたりすることが
  • 8. ベンチマーク(現状) おおむね C, C++ > Rust > Java, Swift, C#, Go > 関数型言語 >>> スクリプト言語 横並び
  • 9. ベンチマーク(現状からいえること) C#は… .NET Core 2.0でちょっと速くなった • C, C++基準で2~3倍遅い • ここを縮めたいという要望は昔から多い • 特定CPU向け最適化 • GC対策 • スクリプト言語基準で3~5倍速い • にもかかわらず「Node.jsと比べてそんなに速くない」と思われてる • 文字列処理の速度が大差ない • 言語的な差よりも、内部のHTTP処理とかの方がネックになったりする
  • 11. ということで今日のテーマ • Span<T> (.NET Core 2.1) • Hardware Intrinsics (.NET Core 2.1より後) • おまけ: .NET Core 2.0での細かい最適化
  • 12. • Span<T> (.NET Core 2.1) • Hardware Intrinsics (.NET Core 2.1より後) • おまけ: .NET Core 2.0での細かい最適化 軽い方から先に
  • 13. 例えばこんなリファクタリング(1) • uint比較 • 効果 • 比較が1回減る • 1命令と言えど、ループで頻繁に呼ばれる処理なので塵も積もる if ((uint)x < length) 元 後 if (0 < x && x < length)
  • 14. 例えばこんなリファクタリング(2) • Common Path Optimization (よく通る場所だけ優先最適化) • 効果 • よく通る場所だけはインライン化が効いて速くなる • (長かったり、throw文があるとインライン化されない) if (9割方true) 短い処理 else 長い処理をメソッド抽出(); if (9割方true) 短い処理 else 長い処理 元 後
  • 15. Q & A (1) • Q. 「この手の細かい改善で5%くらい速くなります」といわれ て、やる? • A. 5%でもやりたい人という人は「世の中にはいる」 • こういうものは、限られた人数では最適化されづらい • コミュニティ貢献が多いらしい • ほんと細かい積み重ねはオープンソース強い
  • 16. Q & A (2) • Q. いまさら? • A 1. .NET Frameworkからの移行で手一杯だったから… • A 2. ほんと、いまさら • 前述のとおり、こういうのはコミュニティ貢献が結構大きい • 「いまさら」というなら、オープン化のタイミングが… • 方針転換 • 最適化はコンパイラーの仕事ではないか → ホットパスは手作業してでも高速化
  • 17. • Span<T> (.NET Core 2.1) • Hardware Intrinsics (.NET Core 2.1より後) • おまけ: .NET Core 2.0での細かい最適化 2.1から外れ ちゃったんで… おまけ程度に
  • 18. C# 対 C言語 • 遅いのはガベージ コレクション(GC)? • → No • スタックの方が速いけどC#でもスタックを主体にしたコードは書ける • そのための機能も年々増えてる(C# 7の構造体活用) • 根本的に(Cでも)ヒープが必要なら、むしろGCは無茶苦茶速い • じゃあ、あと、何が遅いのか? • → 特定CPU向け最適化(CPU専用命令) • 一番犠牲にしてるのはポータビリティ • 要するに、速くしたければ#ifdefだらけ
  • 19. CPU専用命令の例 • 例: SIMD • single instruction multiple data • Vector命令とか言われたり • 例えばSSE(Pentium IIIの頃に導入された原始的なやつ)ですら • 128ビットレジスターを持ってて • float×4の四則演算を1命令でできる • 単純に考えて個別に4回計算する場合の4倍速い • オーバーヘッドの分を差し引いても倍は速い 単一 命令で 複数 データ を一気に処理
  • 20. Hardware Instrinsics • 専用命令の使い方 • 普通のコードを書いて、コンパイラーの最適化に任せる? • 案外、その手のコードを生成してくれない • コンパイラーが特殊な関数を用意 • 「この関数呼び出しは、この命令に置き換える」みたいなコンパイルを行う #include <immintrin.h> __m128 c = _mm_mul_ps(a, b) コンパイラーによって 提供されるライブラリ CPU専用命令に置き換わる
  • 21. Hardware Instrinsics • 専用命令の使い方 • 普通のコードを書いて、コンパイラーの最適化に任せる? • 案外、その手のコードを生成してくれない • コンパイラーが特殊な関数を用意 • 「この関数呼び出しは、この命令に置き換える」みたいなコンパイルを行う #include <immintrin.h> __m128 c = _mm_mul_ps(a, b) こういう関数のことをintrinsicsという • Intrinsic: 内在的な • Hardware Intrinsics: 特定のCPUが内在的に 持っている機能
  • 22. C#でHardware Intrinsics (1) • パッケージ参照 • .NET Core 2.1 preview 1までは、標準に組み込まれる予定だった • 2.1リリースには間に合わず、現状は • パッケージ参照が必要 • 2.1リリース時点では「プレビュー」なパッケージになる予定
  • 23. C#でHardware Intrinsics (2) • コードの書き方 using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; result = Sse.Multiply(Sse.Shuffle(a, a, 0x00), Sse.LoadVector128(p result = Sse.Add(result, Sse.Multiply(Sse.Shuffle(a, a, 0x55), Sse result = Sse.Add(result, Sse.Multiply(Sse.Shuffle(a, a, 0xaa), Sse result = Sse.Add(result, Sse.Multiply(Sse.Shuffle(a, a, 0xff), Sse ・・・ 命令セットの 名前のクラス 命令に対応 するメソッド
  • 24. もちろんCPU依存… • 当然、C言語だと#ifだらけになる • C#でもifだらけになる if (Sse.IsSupported) { return SseAdd(a, b); } else { return Add(a, b); } この命令セットを使える環境の時だけtrue JIT時定数(falseの側は最適化で完全に消える) 使える場合と使えない場合の 2つの実装が必要 かなり速くできるけど、 「ifだらけ」「2重実装」 の覚悟が必要
  • 25. デモ • 行列の積和でベンチマーク • SIMD命令を使うか使わないかでどのくらい速度差が出るか • https://github.com/ufcpp/UfcppSample/tree/master/Demo/2018/Span Performance/MatrixBenchmark
  • 26. • Span<T> (.NET Core 2.1) • Hardware Intrinsics (.NET Core 2.1より後) • おまけ: .NET Core 2.0での細かい最適化 本題。 というか今日の話題で2.1 の話題なのはこれだけに
  • 27. C#対スクリプト言語 • ベンチマーク上は3~5倍は速いはずなのに • Webサーバーとして使うとなんかそこまで差がつかない? • 3~5倍速いのは主に数値計算とか • 文字列処理の速度が大差ない • 言語的な差よりも、内部のHTTP処理(C#やスクリプト言語ではなく、 ネイティブで書かれてる)とかの方がネックになったりする • WebがUTF-8で、C#のstringがUTF-16なのが問題に
  • 28. Webでの文字列処理の例 • 例えばこんな感じのHTTP GETをしたとして • (アップローダーからJSONをダウンロード) • idとnameの値だけを取り出そうとしたとき… ちなみに、こういうJSON
  • 29. 文字列処理の現状 • Stream + stringでの処理 … 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D … 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D Stream.Read(byte[] buffer, int offset, int count) Encoding.GetString(byte[] bytes) … 22 00 69 00 64 00 22 00 3A 00 20 00 31 00 2C 00 0D 00 0A 00 20 00 20 00 22 00 6E 00 61 00 6D 00 65 00 22 00 3A 00 20 00 … string.Substring string.Substring 31 00 1 22 00 3D D8 66 DC 3C D8 FD DF 22 00 "👦🏽" UTF-8 UTF-16
  • 30. 文字列処理をどうしたいか(1) • Nativeヒープを直接参照 … 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D … IPipeReader.TryRead(out ReadResult result) OwnedBuffer 参照管理のための小さいクラス
  • 31. 文字列処理をどうしたいか(2) • UTF-8のままで処理 … 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D … OwnedBuffer Utf8String new Utf8String(buffer.Span)
  • 32. 文字列処理をどうしたいか(3) • 部分参照でコピーを作らない … 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D … OwnedBuffer Utf8String new Utf8String(buffer.Span) Substring Utf8String Utf8String 1 "👦🏽" スタックしか使わない Substringもコピーを作らない 直接intにParse すればヒープ不要 ToString時に 初めてヒープ確保
  • 33. 何が必要か • メモリの一部分を参照 • Nativeヒープを直接 • stringの一部分 • 参照を前提にしたI/O • UTF-8を直接読み書き Span<T>型 Pipelines Utf8String .NET Core 2.1 その後 依存関係 C# 7.0~7.2 • ref戻り値 • ref安全ルール Span<T>型 Pipelines Utf8String 今ここ
  • 34. Span<T>: 「範囲」を参照 • 論理的には、参照+長さ … 7B 0D 0A 20 20 22 69 64 22 3A 20 31 2C 0D 0A 20 20 22 6E 61 6D 65 22 3A 20 22 F0 9F 91 A6 F0 9F 8F BD 22 0D 0A 7D … 1 struct Span<T> { ref T Pointer; int Length; } どこから 何要素 例 ここから1バイト ここから10バイト " "
  • 35. Span<T>: いろんなところ参照 • Managedヒープも、Nativeヒープも、スタックも参照できる Span<byte> span = new byte[N]; Span<byte> span = stackalloc byte[N]; var p = Marshal.AllocHGlobal(N); Span<byte> span = new Span<byte>((byte*)p, N); 普通の配列 = Managedヒープ stackalloc = スタック P/Invokeやunsafe = Nativeヒープ 同じ型で参照できる = 同じロジックで扱える
  • 36. C# 7.2: Span安全ルール • スタック(ローカル変数)の参照を外に返してはいけない ref int Ok(ref int x) { return ref x; } ref int Ng() { int x; return ref x; } Span<int> Ok(Span<int> x) { return x; } Span<int> Ng() { Span<int> x = stackalloc int[1]; return x; } ref安全ルール(C# 7.0) Span<T>※安全ルール(C# 7.2) ローカル変数 (メソッドを抜けると消える) 消えるものの参照 (返そうとするとエラー) ※ 正確にはSpan<T>専用ではなくて、ref構造体に対して掛かる制限
  • 37. C# 7.2: 安全なstackalloc • 例: 頻出数字の検索 static int MostFrequentDigit(string s) { var digits = new int[10]; foreach (var c in s) { var d = c - '0'; if ((uint)d < 10) ++digits[d]; } var max = 0; for (int i = 1; i < 10; i++) if (digits[max] < digits[i]) max = i; return max; } 0~9の文字の頻度をカウント するための一時バッファー 配列のせいでヒープ確保 (あんまり好ましくない)
  • 38. C# 7.2: 安全なstackalloc • 例: 頻出数字の検索 static int MostFrequentDigit(string s) { Span<int> digits = stackalloc int[10]; foreach (var c in s) { var d = c - '0'; if ((uint)d < 10) ++digits[d]; } var max = 0; for (int i = 1; i < 10; i++) if (digits[max] < digits[i]) max = i; return max; } 一時バッファーをnewから stackallocに変更 ヒープ確保がなくなる (速い) unsafe不要 実際、安全 • 範囲チェックあり • 外に返せないルールあり
  • 39. デモ • Substring • ヒープ確保をなくせば無条件に速くなるというものでもない • GCはほんとに速い • Span<T>があるとだいぶ速い • https://github.com/ufcpp/UfcppSample/tree/master/Demo/2018/Span Performance/SubstringBenchmark
  • 40. デモ • Split → Join • string.Splitやstring.Joinは一時的なオブジェクトを確保しまくる • Span<T>でヒープ確保なくSplit, Join • (ただし、使い勝手はあまり良くない) • https://github.com/ufcpp/UfcppSample/tree/master/Demo/2018/Span Performance/StringManipulation
  • 41. まとめ • 2.0~2.1、細かい最適化だらけ • 2.0で実際あったのをちょっと紹介 • Hardware Intrinsics • 2.1から外れちゃったけど • 2.1時点で、プレビュー公開 • Span/UTF-8 • GC速いけど、「ヒープなし」にはさすがに敵わない • そのためのref、Span<T> • C# 7.2で関連機能すでに入ってる/.NET Core 2.1からが本番

Editor's Notes

  1. 最近日本でも「並列処理の言語比較」で見事に炎上したやつがいたけども。まあ、言語比較とか手を出すの危険。
  2. 数値計算処理とかではほんとスクリプト言語は遅い
  3. 「おっ、2.1に入ってんじゃーん」とか思って喜んでスライド作ってたら、「間に合わない。一度外す」って話になった…
  4. 適当なアップローダーに上げたJSONファイルをダウンロードした結果をfiddlerで覗いたもの