はじめに
UnityでStringの連結する際の連結方法によって速度の違いがあるかどうか検証してみました。
※あくまで一例なので環境などにより速度が変わる場合があります。
環境
- Unity 2021.3.10f1
- .NET Standard 2.1
- C# 8.0
公式ドキュメント
Unity - Scripting API: String
複数の文字列を連結する方法 - C#
C# で文字列を連結する方法は複数あります。 各選択のオプションと、それを選ぶ理由も示します。
Stringの連結
各ケースで10000回forでループさせ検証しています。
表示させる文章「19日の天気は晴れ、最高気温は29.5、最低気温は26.4の予報です。」
field(変数宣言部)
enum Wather
{
晴れ,
曇り
}
int day = 19;
Wather weather = Wather.晴れ;
float maxTemp = 29.5f;
float minTemp = 26.4f;
Case1ー「string.Format」を使った方法
msg1 = string.Format("{0}日の天気は{1}、最高気温は{2}、最低気温は{3}の予報です。", day, weather, maxTemp, minTemp);
Stopwatch | Self(ms) | GC Alloc |
21.67ms | 24.13ms | 2.4MB |
Case2ー「+」を使った方法
msg1 = day + "日の天気は" + weather + "、最高気温は" + maxTemp + "、最低気温は" + minTemp + "の予報です。";
Stopwatch | Self(ms) | GC Alloc |
19.77ms | 23.46ms | 3.0MB |
Case3ー「StringBuilder」を使った方法(「+」を使った方法)
sb.Append(day + "日の天気は" + weather + "、最高気温は" + maxTemp + "、最低気温は" + minTemp + "の予報です。");
msg1 = sb.ToString();
Stopwatch | Self(ms) | GC Alloc |
25.62ms | 30.87ms | 6.1MB |
Case3-1ー「StringBuilder」を使った方法(分けて使った方法)
StringBuilder sb = new StringBuilder();
sb.Append(day);
sb.Append("日の天気は");
sb.Append(weather);
sb.Append("、最高気温は");
sb.Append(maxTemp);
sb.Append("、最低気温は");
sb.Append(minTemp);
sb.Append("の予報です。");
msg1 = sb.ToString();
Stopwatch | Self(ms) | GC Alloc |
27.12ms | 29.82ms | 5.6MB |
Case3-2ー「StringBuilder」を使った方法(つなげて使った方法)
StringBuilder sb = new StringBuilder();
sb.Append(day).Append("日の天気は").Append(weather).Append("、最高気温は").Append(maxTemp).Append("、最低気温は").Append(minTemp).Append("の予報です。");
msg1 = sb.ToString();
Stopwatch | Self(ms) | GC Alloc |
24.88ms | 31.05ms | 5.6MB |
Case4ー文字列補間式を使った方法
msg1 = $"{day}日の天気は{weather}、最高気温は{maxTemp}、最低気温は{minTemp}の予報です。";
Stopwatch | Self(ms) | GC Alloc |
20.33ms | 26.33ms | 2.4MB |
Case4-1ー文字列補間式を使った方法(「.ToString」を使った方法)
msg1 = $"{day.ToString()}日の天気は{weather.ToString()}、最高気温は{maxTemp.ToString()}、最低気温は{minTemp.ToString()}の予報です。";
Stopwatch | Self(ms) | GC Alloc |
19.74ms | 24.31ms | 3.0MB |
まとめ
早いのは「Case2」、「Case4-1」となりました。
「Case4-1」は早いのですが冗長な文になって可読性が下がっているので実用的なのは「Case2」、「Case4」かなと筆者的には思いました。
全文
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;
using UnityEngine.Profiling;
using System;
public class test : MonoBehaviour
{
enum Wather
{
晴れ,
曇り
}
int day = 19;
Wather weather = Wather.晴れ;
float maxTemp = 29.5f;
float minTemp = 26.4f;
void Start()
{
//ケース1
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case1();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
//ケース2
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case2();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
//ケース3
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case3();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
//ケース3-1
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case3_1();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
//ケース3-2
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case3_2();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
//ケース4
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case4();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
//ケース4-1
stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
Case4_1();
stopwatch.Stop();
Debug.Log(stopwatch.Elapsed);
}
/// <summary>
/// ケース1
/// </summary>
void Case1()
{
Profiler.BeginSample("1");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
msg1 = string.Format("{0}日の天気は{1}、最高気温は{2}、最低気温は{3}の予報です。", day, weather, maxTemp, minTemp);
}
Debug.Log(msg1);
Profiler.EndSample();
}
/// <summary>
/// ケース2
/// </summary>
void Case2()
{
Profiler.BeginSample("2");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
msg1 = day + "日の天気は" + weather + "、最高気温は" + maxTemp + "、最低気温は" + minTemp + "の予報です。";
}
Debug.Log(msg1);
Profiler.EndSample();
}
/// <summary>
/// ケース3
/// </summary>
void Case3()
{
Profiler.BeginSample("3");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
StringBuilder sb = new StringBuilder();
sb.Append(day + "日の天気は" + weather + "、最高気温は" + maxTemp + "、最低気温は" + minTemp + "の予報です。");
msg1 = sb.ToString();
}
Debug.Log(msg1);
Profiler.EndSample();
}
/// <summary>
/// ケース3-1
/// </summary>
void Case3_1()
{
Profiler.BeginSample("3-1");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
StringBuilder sb = new StringBuilder();
sb.Append(day);
sb.Append("日の天気は");
sb.Append(weather);
sb.Append("、最高気温は");
sb.Append(maxTemp);
sb.Append("、最低気温は");
sb.Append(minTemp);
sb.Append("の予報です。");
msg1 = sb.ToString();
}
Debug.Log(msg1);
Profiler.EndSample();
}
/// <summary>
/// ケース3-2
/// </summary>
void Case3_2()
{
Profiler.BeginSample("3-2");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
StringBuilder sb = new StringBuilder();
sb.Append(day).Append("日の天気は").Append(weather).Append("、最高気温は").Append(maxTemp).Append("、最低気温は").Append(minTemp).Append("の予報です。");
msg1 = sb.ToString();
}
Debug.Log(msg1);
Profiler.EndSample();
}
/// <summary>
/// ケース4
/// </summary>
void Case4()
{
Profiler.BeginSample("4");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
msg1 = $"{day}日の天気は{weather}、最高気温は{maxTemp}、最低気温は{minTemp}の予報です。";
}
Debug.Log(msg1);
Profiler.EndSample();
}
/// <summary>
/// ケース4-1
/// </summary>
void Case4_1()
{
Profiler.BeginSample("4-1");
string msg1 = "";
for (int i = 0; i < 10000; i++)
{
msg1 = "";
msg1 = $"{day.ToString()}日の天気は{weather.ToString()}、最高気温は{maxTemp.ToString()}、最低気温は{minTemp.ToString()}の予報です。";
}
Debug.Log(msg1);
Profiler.EndSample();
}
}
コメント