SlideShare a Scribd company logo
1 of 20
Download to read offline
C#のキモイ⾼速プログラミング
群⾺⾼専 5年 電⼦メディア⼯学科
ぎもちん (@SKKbySSK_TC)
C#には⾯⽩い機能がたくさんある
foreach
Attribute
Reflection
ref struct
unsafe
fixed
GC
unsafe とは?
C#でポインタ操作を可能にする
int x = 50;
int* ptr = &x; // xのポインタを取り出す
*ptr /= 2; // ポインタの指すデータを2で割る(50 / 2 = 25)
Console.WriteLine(x);
Output
25
今回やること
byte[]をfloat[]へ変換する
1. 単純な変換⽅法
BitConverter と for を使って変換する
const int size = 1024;
byte[] source = new byte[size]; //変換前データ
float[] converted = new float[size / sizeof(float)]; //変換後データ
for (int i = 0; i < converted.Length; i++)
{
converted[i] = BitConverter.ToSingle(source, i * 4);
}
2. unsafeによる変換⽅法
const int size = 1024;
byte[] source = new byte[size]; //変換前データ
float[] converted = new float[size / sizeof(float)]; //変換後データ
// 配列のアドレスを⼀時的に固定する
fixed (float* convertedPtr = converted)
fixed (byte* sourcePtr = source)
{
// byte* -> float*へキャストして4バイトずつ処理する
float* floatSourcePtr = (float*)sourcePtr;
for (int i = 0; i < converted.Length; i++)
{
convertedPtr[i] = floatSourcePtr[i];
}
}
結果
BenchmarkDotNetを使って測定
ArrayConversionTest.cs
Method 平均
単純な変換 1,534.6059 ns
unsafeによる変換 783.1249 ns
※ 変換前データを初期化する時間は含んでいません
早いぞ!でも・・・
メモリの固定や確保によるオーバーヘッド
変換後のデータ格納⽤配列が余計にメモリ喰う
byte配列をfloat配列として使えばええやん
構造体を使おう!
構造体
C#では構造体のメモリ構造を指定できる
Cの union みたいなことができる
StructLayout と FieldOffset 属性を組み合わせる
例
// メモリ構造を明⽰することをコンパイラに伝える
[StructLayout(LayoutKind.Explicit)]
struct SampleStruct
{
[FieldOffset(0)] // 0バイト⽬にAを配置する
public int A;
[FieldOffset(2)] // 2バイト⽬にBを配置する
public byte B;
}
SampleStruct data = new SampleStruct();
data.A = 0xDDCCBBAA;
Console.WriteLine(data.B); // 187(0xBB)
※エンディアンによっては 204(0xCC) と出る場合もあります
メモリレイアウト
3. Unionもどき
[StructLayout(LayoutKind.Explicit)]
struct UnionArray
{
[FieldOffset(0)]
public float[] Float;
[FieldOffset(0)]
public byte[] Byte;
}
const int size = 1024;
byte[] source = new byte[size]; //変換前データ
UnionArray union = new UnionArray() { Byte = source };
float[] converted = union.Float;
もう⼀度計測!!
結果
測定条件は前回と同じ
Method 平均
単純な変換 1,534.6059 ns
unsafeによる変換 783.1249 ns
Unionもどきによる変換 0.9233 ns
圧倒的パフォーマンス!!
Unionもどきの注意点
境界チェックが狂う
配列の⻑さを記録しているメモリが書き変わらないた
め
無理やり書き換える⽅法は以下参照
ArrayConversionTest.cs#L68-L84
型情報も狂う
同様に、型情報のメモリも書き変わらないため
⽤量・⽤法はほどほどに
可読性がとても悪い
メモリを意識する必要がある
オーディオプロセッシング等ではかなり便利
単純な変換⽅法でも⼗分早い
ご清聴ありがとうございました!
楽しいC#ライフを!

More Related Content

What's hot

クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!Genya Murakami
 
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法Yoshifumi Kawai
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!amusementcreators
 
Protocol Buffers 入門
Protocol Buffers 入門Protocol Buffers 入門
Protocol Buffers 入門Yuichi Ito
 
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」U-dai Yokoyama
 
[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User Namespaces[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User NamespacesAkihiro Suda
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
データで散らかった製造業界における最高の翻訳機 Node-RED
データで散らかった製造業界における最高の翻訳機 Node-REDデータで散らかった製造業界における最高の翻訳機 Node-RED
データで散らかった製造業界における最高の翻訳機 Node-REDnodered_ug_jp
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)NTT DATA Technology & Innovation
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと信之 岩永
 
Rclex: ElixirでROS!!
Rclex: ElixirでROS!!Rclex: ElixirでROS!!
Rclex: ElixirでROS!!Hideki Takase
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能Kohei Tokunaga
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みTakeshi Ogawa
 
Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#Yoshifumi Kawai
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)mosa siru
 

What's hot (20)

クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
ZeroFormatterに見るC#で最速のシリアライザを作成する100億の方法
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!コルーチンでC++でも楽々ゲーム作成!
コルーチンでC++でも楽々ゲーム作成!
 
Protocol Buffers 入門
Protocol Buffers 入門Protocol Buffers 入門
Protocol Buffers 入門
 
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
 
[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User Namespaces[Container Runtime Meetup] runc & User Namespaces
[Container Runtime Meetup] runc & User Namespaces
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
データで散らかった製造業界における最高の翻訳機 Node-RED
データで散らかった製造業界における最高の翻訳機 Node-REDデータで散らかった製造業界における最高の翻訳機 Node-RED
データで散らかった製造業界における最高の翻訳機 Node-RED
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
 
C#とILとネイティブと
C#とILとネイティブとC#とILとネイティブと
C#とILとネイティブと
 
C#で速度を極めるいろは
C#で速度を極めるいろはC#で速度を極めるいろは
C#で速度を極めるいろは
 
Rclex: ElixirでROS!!
Rclex: ElixirでROS!!Rclex: ElixirでROS!!
Rclex: ElixirでROS!!
 
BuildKitの概要と最近の機能
BuildKitの概要と最近の機能BuildKitの概要と最近の機能
BuildKitの概要と最近の機能
 
Docker Compose 徹底解説
Docker Compose 徹底解説Docker Compose 徹底解説
Docker Compose 徹底解説
 
さくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組みさくっと理解するSpring bootの仕組み
さくっと理解するSpring bootの仕組み
 
Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)
 

Similar to C#のキモイ高速プログラミング

.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#信之 岩永
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cythonfuzzysphere
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11えぴ 福田
 
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
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputingNoboru Irieda
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cythonAtsuo Ishimoto
 
New Features in C# 10/11
New Features in C# 10/11New Features in C# 10/11
New Features in C# 10/11Akira Inoue
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2Tomohiro Namba
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61TATSUYA HAYAMIZU
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語るAkira Takahashi
 
Rtm講習会 140626 02
Rtm講習会 140626 02Rtm講習会 140626 02
Rtm講習会 140626 02openrtm
 
言語処理系入門€10
言語処理系入門€10言語処理系入門€10
言語処理系入門€10Kenta Hattori
 
C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)Akira Takahashi
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門Shiqiao Du
 
130710 02
130710 02130710 02
130710 02openrtm
 

Similar to C#のキモイ高速プログラミング (20)

.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#.NET Core 2.x 時代の C#
.NET Core 2.x 時代の C#
 
Wrapping a C++ library with Cython
Wrapping a C++ library with CythonWrapping a C++ library with Cython
Wrapping a C++ library with Cython
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
 
Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)
 
Python physicalcomputing
Python physicalcomputingPython physicalcomputing
Python physicalcomputing
 
Introduction to cython
Introduction to cythonIntroduction to cython
Introduction to cython
 
C++0x総復習
C++0x総復習C++0x総復習
C++0x総復習
 
New Features in C# 10/11
New Features in C# 10/11New Features in C# 10/11
New Features in C# 10/11
 
研究生のためのC++ no.2
研究生のためのC++ no.2研究生のためのC++ no.2
研究生のためのC++ no.2
 
わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61わんくま同盟大阪勉強会#61
わんくま同盟大阪勉強会#61
 
C++0x 言語の未来を語る
C++0x 言語の未来を語るC++0x 言語の未来を語る
C++0x 言語の未来を語る
 
Rtm講習会 140626 02
Rtm講習会 140626 02Rtm講習会 140626 02
Rtm講習会 140626 02
 
言語処理系入門€10
言語処理系入門€10言語処理系入門€10
言語処理系入門€10
 
C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)
 
Boost Tour 1.53.0 merge
Boost Tour 1.53.0 mergeBoost Tour 1.53.0 merge
Boost Tour 1.53.0 merge
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
130710 02
130710 02130710 02
130710 02
 

C#のキモイ高速プログラミング