はじめに
// for 文 for (int i = 0; i < array.Length; i++) { Debug.Log(array[i]); } // for 文(ループ回数を変数にキャッシュ) int max = array.Length; for (int i = 0; i < max; i++) { Debug.Log(array[i]); } // foreach 文 foreach (var n in array) { Debug.Log(n); } // Array クラスの ForEach 関数 Array.ForEach(array, c => Debug.Log(c));
C#のループ構文で一番処理速度が高速なのはどの書き方なのか気になったので
Unityでいろいろなループ構文でDebug.Logを実行して処理速度を比較してみました
※Unityのバージョンは4.3.4です
検証結果
配列の場合
ループ方法 | 要素数 100 | 要素数 1,000 | 要素数 10,000 |
---|---|---|---|
for (int i = 0; i < array.Length; i++) {} | 0.05620767 秒 | 0.5522295 秒 | 5.4827800 秒 |
for (int i = 0; i < num; i++) {} | 0.05693574 秒 | 0.5462796 秒 | 5.4543830 秒 |
foreach (var n in array) {} | 0.05319814 秒 | 0.5503743 秒 | 5.4594120 秒 |
Array.ForEach(array, c => {}); | 0.11020360 秒 | 1.1172990 秒 | 11.182310 秒 |
List の場合
ループ方法 | 要素数 100 | 要素数 1,000 | 要素数 10,000 |
---|---|---|---|
for (int i = 0; i < list.Count; i++) {} | 0.05819568 秒 | 0.5498013 秒 | 5.4457230 秒 |
for (int i = 0; i < num; i++) {} | 0.05440858 秒 | 0.5452724 秒 | 5.4431950 秒 |
foreach (var n in list) {} | 0.05427125 秒 | 0.5507185 秒 | 5.4520870 秒 |
list.ForEach(c => {}); | 0.11904870 秒 | 1.1715450 秒 | 11.893260 秒 |
感想
for 文を使用した場合と foreach 文を使用した場合で速度は変わらなかったので
ソースコードを簡潔に書くためにも foreach 文を使用できる場合は
foreach 文を使用したほうが良さそうです
また、for 文を使用するときにループ回数(配列やリストの要素数)を
変数にキャッシュする場合としない場合でも速度は変わらなかったです
Array.ForEach 関数や List.ForEach 関数は for 文や foreach 文と比べて 2 倍ほど遅くなりました
検証用スクリプト
using UnityEngine; using System.Collections; using System; using System.Collections.Generic; using System.Linq; using System.Text; public class for_test : MonoBehaviour { public int m_element_num = 1000; public float m_array_for1_time = 0.0f; public float m_array_for2_time = 0.0f; public float m_array_foreach_time = 0.0f; public float m_array_ArrayForEach_time = 0.0f; public float m_list_for1_time = 0.0f; public float m_list_for2_time = 0.0f; public float m_list_foreach_time = 0.0f; public float m_list_ListForEach_time = 0.0f; void Start() { var array = new int[m_element_num]; var list = new List<int>(); for (int i = 0; i < m_element_num; i++) { list.Add(0); } m_array_for1_time = Time.realtimeSinceStartup; for (int i = 0; i < array.Length; i++) { Debug.Log(array[i]); } m_array_for1_time = Time.realtimeSinceStartup - m_array_for1_time; var max = array.Length; m_array_for2_time = Time.realtimeSinceStartup; for (int i = 0; i < max; i++) { Debug.Log(array[i]); } m_array_for2_time = Time.realtimeSinceStartup - m_array_for2_time; m_array_foreach_time = Time.realtimeSinceStartup; foreach (var n in array) { Debug.Log(n); } m_array_foreach_time = Time.realtimeSinceStartup - m_array_foreach_time; m_array_ArrayForEach_time = Time.realtimeSinceStartup; Array.ForEach(array, c => Debug.Log(c)); m_array_ArrayForEach_time = Time.realtimeSinceStartup - m_array_ArrayForEach_time; m_list_for1_time = Time.realtimeSinceStartup; for (int i = 0; i < list.Count; i++) { Debug.Log(list[i]); } m_list_for1_time = Time.realtimeSinceStartup - m_list_for1_time; max = list.Count; m_list_for2_time = Time.realtimeSinceStartup; for (int i = 0; i < max; i++) { Debug.Log(list[i]); } m_list_for2_time = Time.realtimeSinceStartup - m_list_for2_time; m_list_foreach_time = Time.realtimeSinceStartup; foreach (var n in list) { Debug.Log(n); } m_list_foreach_time = Time.realtimeSinceStartup - m_list_foreach_time; m_list_ListForEach_time = Time.realtimeSinceStartup; list.ForEach(c => Debug.Log(c)); m_list_ListForEach_time = Time.realtimeSinceStartup - m_list_ListForEach_time; Debug.Log("a_for1 " + m_array_for1_time); Debug.Log("a_for2 " + m_array_for2_time); Debug.Log("a_fore " + m_array_foreach_time); Debug.Log("a_afore " + m_array_ArrayForEach_time); Debug.Log("l_for1 " + m_list_for1_time); Debug.Log("l_for2 " + m_list_for2_time); Debug.Log("l_fore " + m_list_foreach_time); Debug.Log("l_lfore " + m_list_ListForEach_time); } }