Span<T>構造体を使ってみた。
はじめに
C#のお勉強としてufcppさんの未確認飛行Cを読んでいたらSpan構造体というものがあることを知ったので実際に使ってみました。
Span構造体
以下、ufcppさんの記事がとても分かりやすかったので引用させていただきます。
Span構造体(System名前空間)は、span (区間、範囲)という名前通り、連続してデータが並んでいるもの(配列など)の一定範囲を読み書きするために使う型です。
実際に使ってみる
本当はもっと深くSpan
今回は引用させていただいた記事内において、文字列をSubStringではなくSpan
(もちろんSubStringとSpan
SubStringとSpan構造体
以下は100文字の文字列の4文字目から85文字分抜き出して変数に格納する時間をそれぞれ計っています(100万回ループ)。
static void Main(string[] args) { var s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; var sw = new System.Diagnostics.Stopwatch(); sw.Start(); for (int i = 0; i < 1000000; i++) { var sub = s.Substring(3, 85); } sw.Stop(); TimeSpan ts = sw.Elapsed; Console.WriteLine($"{ts.Seconds}秒 {ts.Milliseconds}ミリ秒"); var sw2 = new System.Diagnostics.Stopwatch(); sw2.Start(); for (int i = 0; i < 1000000; i++) { var span = s.AsSpan().Slice(3, 85); } sw2.Stop(); TimeSpan ts2 = sw2.Elapsed; Console.WriteLine($"{ts2.Seconds}秒 {ts2.Milliseconds}ミリ秒"); }
0秒 26ミリ秒 <-- SubString 0秒 13ミリ秒 <-- Span<T>
なるほど。確かにコピーしていない分Spanのほうが速いみたいです。
ArraySegmentとSpan構造体
以下は配列の3要素目から15要素取得して変数に格納する時間をそれぞれ計っています(100万回ループ)。
static void Main(string[] args) { var array = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; var sw = new System.Diagnostics.Stopwatch(); sw.Start(); Console.WriteLine(new ArraySegment<int>(array, 2, 15)); for (int i = 0; i < 1000000; i++) { var arySeg = new ArraySegment<int>(array, 2, 15); } sw.Stop(); TimeSpan ts = sw.Elapsed; Console.WriteLine($"{ts.Seconds}秒 {ts.Milliseconds}ミリ秒"); var sw2 = new System.Diagnostics.Stopwatch(); sw2.Start(); Console.WriteLine(new Span<int>(array, 2, 15).ToString()); for (int i = 0; i < 1000000; i++) { var spanArr = new Span<int>(array, 2, 15); } sw2.Stop(); TimeSpan ts2 = sw2.Elapsed; Console.WriteLine($"{ts2.Seconds}秒 {ts2.Milliseconds}ミリ秒"); }
0秒 7ミリ秒 <-- ArraySegment 0秒 4ミリ秒 <-- Span<T>構造体
おお~。こちらは誤差かな?と思って何度か試してみましたが、やはりSpan
おわりに
まだまだSpan