LoginSignup
2
3

More than 3 years have passed since last update.

UnityでListの最小値を取得する最速の方法

Last updated at Posted at 2020-01-18

A*経路探索のコードを書いていてListの最小値を取得する最速の方法が気になったので検証してみました。
前回、速度比較のやり方を模索してみたのはこの為だったりします。

for文 vs Min()

普通にfor文で全要素を一つづつ比較していくのとlinqのMin()を使うのではどっちが速いんでしょうか?

コードは以下です。
0~100000のランダムな整数の入った要素数10万のListを宣言してその中から最小値を取得、
Profiler.BeginSample/EndSampleで、最小値を取得する部分だけを計測しています。

public class MinTest {

    //for文のやつ
    [Test]
    public void UseFor() {
        var randamValues = GetRandamValues();
        Profiler.BeginSample("MinTest.UseFor");
        var min = randamValues[0];
        for (int i = 1; i < randamValues.Count; i++) {
            min = randamValues[i] < min ? randamValues[i] : min;
        }
        Profiler.EndSample();
        Debug.Log(min);
    }

    //Min()
    [Test]
    public void UseMin() {
        var randamValues = GetRandamValues();
        Profiler.BeginSample("MinTest.UseListMin");
        var min = randamValues.Min();
        Profiler.EndSample();
        Debug.Log(min);
    }

    List<int> GetRandamValues() {
        var randamValues = new List<int>();
        for (int i = 0; i < 100000; i++) {
            randamValues.Add(Random.Range(0, 100000));
        }
        return randamValues;
    }
}

結果

GC Alloc Time
UseFor 0B 1.18ms
UseMin 40B 1.49ms

速度には気にするほどの差は出ませんが、Min()はGC Allocが発生してしまいますね。

条件分岐の書き方で差は出るの?

やっぱり普通にfor文使うのが速いですね。
しかし、もう一つ気になることがあります。
条件分岐の書き方で差が出るかどうかです。

//for文のやつ
    [Test]
    public void UseFor() {
        var randamValues = GetRandamValues();
        Profiler.BeginSample("MinTest.UseFor");
        var min = randamValues[0];
        for (int i = 1; i < randamValues.Count; i++) {
            min = randamValues[i] < min ? randamValues[i] : min;//←ここの書き方で差は出るの?
        }
        Profiler.EndSample();
        Debug.Log(min);
    }

以下の3つを試してみます

①if文

if (randamValues[i] < min) min = randamValues[i];

②条件演算子

min = randamValues[i] < min ? randamValues[i] : min;

③条件演算子(条件式を反転)

min = randamValues[i] >= min ? min : randamValues[i];

結果

誤差で結果が上下するので、1000回の平均を計測しました。
微妙に差が出ますが、気にするレベルではないですね。

GC Alloc Time
①if文 0B 1.28120ms
②条件演算子 0B 1.26898ms
③条件演算子(条件式を反転) 0B 1.24765ms

まとめ

普通にfor文使うのが速いしGC Allocも発生しない!

ご意見ご感想、多分これが一番速いと思います等ありましたらコメントを頂けますと幸いです!

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3