Cygames の子会社 Cy# さんが出してる C# のOSSライブラリ。メモリ消費量が少なく、早い(?)
細かい内容は上の Cy# さんのブログに書かれています。
試したコード
using System; using System.IO; using Cysharp.Text; namespace ZStringTestDotnetCore { class Program { static void Main(string[] args) { var ts1 = MeasureTask(ZStringConcat); var ts2 = MeasureTask(MemoryStreamStringFormat); var ts3 = MeasureTask(ZStringFormatUtf8); var ts4 = MeasureTask(ZStringFormatUtf16); var ts5 = MeasureTask(MemoryStreamZStringFormat); Console.Write($"- ZString(Concat) {ts1}\n"); Console.Write($"- Memory Stream 1 {ts2}\n"); Console.Write($"- ZString(Format) A {ts3}\n"); Console.Write($"- ZString(Format) B {ts4}\n"); Console.Write($"- Memory Stream 2 {ts5}\n"); } static TimeSpan MeasureTask(Action func) { var sw = new System.Diagnostics.Stopwatch(); sw.Reset(); sw.Start(); func(); sw.Stop(); return sw.Elapsed; } static void ZStringConcat() { int i = 0,j = 0,k = 0; using (var sb = ZString.CreateUtf8StringBuilder()) { while (i < 300000) { var now = DateTime.Now; sb.Append(ZString.Concat("i:", i, ",j:", j , ",k:", k, "\n")); i++; j += 2; k += 3; } sb.WriteToAsync(Console.OpenStandardOutput()).Wait(); } } static void MemoryStreamStringFormat() { int i = 0,j = 0,k = 0; using(var ms = new MemoryStream()) { using (var wr = new StreamWriter(ms)) { while (i < 300000) { var now = DateTime.Now; wr.Write(string.Format("i:{0},j:{1},k:{2}\n", i, j, k)); i++; j += 2; k += 3; } wr.Flush(); ms.WriteTo(Console.OpenStandardOutput()); } } } static void ZStringFormatUtf8() { int i = 0, j = 0, k = 0; using (var sb = ZString.CreateUtf8StringBuilder()) { while (i < 300000) { var now = DateTime.Now; sb.Append(ZString.Format("i:{0},j:{1},k:{2}\n", i, j, k)); i++; j += 2; k += 3; } sb.WriteToAsync(Console.OpenStandardOutput()).Wait(); } } static void ZStringFormatUtf16() { int i = 0, j = 0, k = 0; using (var sb = ZString.CreateStringBuilder()) { while (i < 300000) { var now = DateTime.Now; sb.Append(ZString.Format("i:{0},j:{1},k:{2}\n", i, j, k)); i++; j += 2; k += 3; } Console.WriteLine(sb.ToString()); } } static void MemoryStreamZStringFormat() { int i = 0, j = 0, k = 0; using (var ms = new MemoryStream()) { using (var wr = new StreamWriter(ms)) { while (i < 300000) { var now = DateTime.Now; wr.Write(ZString.Format("i:{0},j:{1},k:{2}\n", i, j, k)); i++; j += 2; k += 3; } wr.Flush(); ms.WriteTo(Console.OpenStandardOutput()); } } } } }
結果
- ZString(Concat) 00:00:02.9890532 - Memory Stream 1 00:00:02.6363530 - ZString(Format) A 00:00:02.6669643 - ZString(Format) B 00:00:03.3741640 - Memory Stream 2 00:00:02.6118988
私の試したコードではあまり早くなりませんでした。MemoryStream + StreamWriter のほうがちょっと早いかなという感じ。ここでは記載していませんが、メモリ消費量もあまり違いがない感じでした。もしかすると、ZString は Unity との親和性に重きを置いているので、もしかするとこういうコードではあまり恩恵は受けれないのかもです。
ただ、StringBuilder と比較すると WriteToAsync() メソッドがあって便利ですし、 UTF8用のBuilderもあるので、そちらも便利そうです。