Unity2018での文字列の扱い方
概略
Unityで文字列の連結を行う方法として以下の3つのパフォーマンスを比較してみました。1000回ループし文字列を連結させた時の処理時間とGC回数を計測しました。
- string(StingTest)
- stringBuilder(StringBuilderTest)
- 文字列補間(BuildInStringTest)
- C#6から導入: https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/tokens/interpolated
- 変数をインラインで文字列に埋め込むことができる
ソースコード
using System; using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; public class LinkStringSample : MonoBehaviour { private const int N = 10000; public void StingTest() { int starttime = DateTime.Now.Hour * 60 *60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; string str = string.Empty; for (int i = 0; i < N; i++) { str += "aaa"; } int now = DateTime.Now.Hour * 60 * 60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; Debug.Log($"StingTest()実行時間: {now - starttime}ms"); // GC.CollectionCountはプロスを起動してからのGC回数を返す // https://msdn.microsoft.com/ja-jp/library/system.gc.collectioncount(v=vs.110).aspx Debug.Log($"GC回数: {GC.CollectionCount(0)}回"); } public void StringBuilderTest() { int starttime = DateTime.Now.Hour * 60 *60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; StringBuilder strBuilder = new StringBuilder(); for (int i = 0; i < N; i++) { strBuilder.Append("aaa"); } int now = DateTime.Now.Hour * 60 * 60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; Debug.Log($"StringBuilderTest()実行時間: {now - starttime}ms"); Debug.Log($"GC回数: {GC.CollectionCount(0)}回"); } public void BuildInStringTest() { int starttime = DateTime.Now.Hour * 60 *60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; string str = String.Empty; for (int i = 0; i < N; i++) { str = $"{str}aaa"; } int now = DateTime.Now.Hour * 60 * 60 * 1000 + DateTime.Now.Minute * 60 * 1000 + DateTime.Now.Second * 1000 + DateTime.Now.Millisecond; Debug.Log($"BuildInStringTest()実行時間: {now - starttime}ms"); Debug.Log($"GC回数: {GC.CollectionCount(0)}回"); } }
検証環境
結果
StingTest | StringBuilderTest | BuildInStringTest | |
---|---|---|---|
Editor | 511/168 | 0.6/56 | 1248/288 |
ios | 234/1577 | 0.6/6 | 542/3885 |
android | 708/2015 | 1.0/6 | 1613/5656 |
まとめ
- 文字列の連結には基本的にはStringBuilderを使うのがよい
- 特にインライン形式での埋め込みは高コストなのでDebugログなどの限定的な使用に留めるべきである