0. 言い訳から...
えーと、Unity Advent Calendar 2023 シリーズ2の9日目です...全然タイムアウトぉお!!
なかなか書くネタが思いつかず、こんなに遅れてしまいましたが、まぁインターネットのどこかには落ちておいてほしい検証記事を今年も投稿しようと思います。
余談ですが、「今年も」と言っておりますが、前年も検証記事を書いていました。
今年一年で結構な人に読まれたようで、引用とかもしていただいたみたいです。
ありがとうございますm(__)m
1. 本題
さて、この記事の本題は、Unityで使用できる算術関連クラスのパフォーマンス比較です。
UnityEngineには標準で Mathf
クラスが搭載されており、幅広く使用されているかと思いますが、C#のSystem名前空間にも標準で、Math
クラスが提供されています。
この二つは無関係な代物ではなく、UnityEngine.Mathf
には単純に System.Math
のメソッドをラップしているだけのものがあることも知られています。
単なるラップメソッドは当然のことながら、モノホンの System.Math
には勝てないでしょう。それは自明の理。
しかし、UnityEngine.Mathf
クラスは、全部が全部 System.Math
クラスのRapperというわけではありません。
そもそも UnityEngine.Mathf
クラスにだけあって System.Math
クラスにないメソッドというものもありますが、共通であるものでもラップ関係にないものもあります。
例えば、UnityEngine.Mathf.Max()
メソッド。
このメソッドの定義は以下の通りです。
(引数違いで色々と定義があるので、シンプルなfloat型2つの比較のものを掲載します。)
public static float Max(float a, float b) => (double) a > (double) b ? a : b;
わかりやすくていいですね。
まあ、見ての通り、このメソッドに関しては System.Math
クラスをラップしていません。
ではどちらが速いのか...メモリに優しいのか...それを検証するのが今回の記事になります。
2.検証方法
検証方法はありきたりですが、プロファイラーを使った計測になります。
using System;
using System.Collections;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Profiling;
public sealed class Benchmark : MonoBehaviour
{
IEnumerator Start()
{
// 5秒経過したくらいから計測開始
yield return new WaitForSeconds(5);
Profiler.BeginSample(nameof(Mathf.Max));
for (int i = 0; i < 10000; i++)
{
float result = Mathf.Max(10.5f, 11.4f);
}
Profiler.EndSample();
Profiler.BeginSample(nameof(math.max));
for (int i = 0; i < 10000; i++)
{
float result = math.max(10.5f, 11.4f);
}
Profiler.EndSample();
Profiler.BeginSample(nameof(Math.Max));
for (int i = 0; i < 10000; i++)
{
float result = Math.Max(10.5f, 11.4f);
}
Profiler.EndSample();
Profiler.BeginSample(nameof(MathF.Max));
for (int i = 0; i < 10000; i++)
{
float result = MathF.Max(10.5f, 11.4f);
}
Profiler.EndSample();
}
}
こんな感じで、10000回実行したときのパフォーマンスを比較していきます。
Deep Profile
オンでこれを実際に実行すると、以下の結果が得られます。
上の例の場合、GCアロケーションは問題なし、速度・負荷ともに Mathf.Max()
の勝利!でいいと思います。
こんな感じでガリガリ検証していきたいと思います。
・Unity 2022.3.12f
・Mono
・.Net Standard2.1
・Mathematics1.2.6
3. 検証結果
基本的に、Mathfベースで、他のものでそれに相当するものと比較していきます。
Unity.Mathematics.math
とかは、UnityEngine.Mathf
と違う用途で派生しているものなので、単純比較ができるとはそもそも考えていません。
単に、普段使いはどれがいいかな?って検証です。
3-1. Static変数
さすがに定数はGCアロケーションもアクセス速度も0ですね。
内部が public const
なので、差がつくわけもなし...。
Unity.Mathematic.math.radius()
は厳密にはメソッドなので定数ではないのですが、相当対象として並べておきました。
$\small\texttt{UnityEngine.Mathf}$ | $\small\texttt{Unity.Mathematics.math}$ | $\small\texttt{System.Math}$ | $\small\texttt{System.MathF}$ | ||||||||
$\small\texttt{比較対象}$ | $\small\texttt{GC Alloc (B)}$ | $\small\texttt{Time (ms)}$ | $\small\texttt{相当対象}$ | $\small\texttt{GC Alloc}$ | $\small\texttt{Time (ms)}$ | $\small\texttt{相当対象}$ | $\small\texttt{GC Alloc}$ | $\small\texttt{Time (ms)}$ | $\small\texttt{相当対象}$ | $\small\texttt{GC Alloc}$ | $\small\texttt{Time (ms)}$ |
$\small\texttt{float Deg2Rad}$ | 0 | 0 | $\small\texttt{float radians()}$ | 0 | 0.48 | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ | ||||
$\small\texttt{float Epsilon}$ | 0 | 0 | $\small\texttt{float EPSILON}$ | 0 | 0 | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ | ||||
$\small\texttt{float Infinity}$ | 0 | 0 | $\small\texttt{float INFINITY}$ | 0 | 0 | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ | ||||
$\small\texttt{float NegativeInfinity}$ | 0 | 0 | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ | ||||||
$\small\texttt{float PI}$ | 0 | 0 | $\small\texttt{float PI}$ | 0 | 0 | $\small\texttt{該当なし}$ | $\small\texttt{(Math.PIはdouble型)}$ | $\small\texttt{float PI}$ | 0 | 0 | |
$\small\texttt{float Rad2Deg}$ | 0 | 0 | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ | $\small\texttt{該当なし}$ |
3-2. Statuc関数
こちらが本題ですね。
相対対象は自分調べなので、「該当なし」にしているものも、もしかしたらあるかもです。
$\small\texttt{UnityEngine.Mathf}$ | $\small\texttt{Unity.Mathematics.math}$ | $\small\texttt{System.Math}$ | $\small\texttt{System.MathF}$ | ||||||||
$\small\texttt{比較対象}$ | $\small\texttt{GC Alloc (B)}$ | $\small\texttt{Time (ms)}$ | $\small\texttt{相当対象}$ | $\small\texttt{GC Alloc}$ | $\small\texttt{Time ms}$ | $\small\texttt{相当対象}$ | $\small\texttt{GC Alloc}$ | $\small\texttt{Time ms}$ | $\small\texttt{相当対象}$ | $\small\texttt{GC Alloc}$ | $\small\texttt{Time ms}$ |
$\small\texttt{float Abs (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.37}$ | $\small\texttt{float abs}$ | $\small\texttt{0}$ | $\small\texttt{4.23}$ | $\small\texttt{float Abs}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{float Abs}$ | $\small\texttt{0}$ | $\small\texttt{1.47}$ |
$\small\texttt{int Abs (int value)}$ | $\small\texttt{0}$ | $\small\texttt{1.35}$ | $\small\texttt{int abs}$ | $\small\texttt{0}$ | $\small\texttt{1.38}$ | $\small\texttt{int abs}$ | $\small\texttt{0}$ | $\small\texttt{0.42}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Acos (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.45}$ | $\small\texttt{float acos}$ | $\small\texttt{0}$ | $\small\texttt{1.43}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Acosはdouble型)}$ | $\small\texttt{float Acos}$ | $\small\texttt{0}$ | $\small\texttt{0.52}$ | |
$\small\texttt{bool Approximately (float a, float b)}$ | $\small\texttt{0}$ | $\small\texttt{7.86}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Asin (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.57}$ | $\small\texttt{float asin}$ | $\small\texttt{0}$ | $\small\texttt{1.38}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Asinはdouble型)}$ | $\small\texttt{float Asin}$ | $\small\texttt{0}$ | $\small\texttt{0.51}$ | |
$\small\texttt{float Atan (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.59}$ | $\small\texttt{float atan}$ | $\small\texttt{0}$ | $\small\texttt{1.50}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Atanはdouble型)}$ | $\small\texttt{float Atan}$ | $\small\texttt{0}$ | $\small\texttt{0.64}$ | |
$\small\texttt{float Atan2 (float y, float x)}$ | $\small\texttt{0}$ | $\small\texttt{3.47}$ | $\small\texttt{float atan2}$ | $\small\texttt{0}$ | $\small\texttt{1.52}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Atan2はdouble型)}$ | $\small\texttt{float Atan2}$ | $\small\texttt{0}$ | $\small\texttt{0.61}$ | |
$\small\texttt{float Ceil (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.50}$ | $\small\texttt{float ceil}$ | $\small\texttt{0}$ | $\small\texttt{0.49}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Ceilingはdouble型)}$ | $\small\texttt{float Ceiling}$ | $\small\texttt{0}$ | $\small\texttt{0.50}$ | |
$\small\texttt{int CeilToInt (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.51}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Clamp (float value, float min, float max)}$ | $\small\texttt{0}$ | $\small\texttt{0.46}$ | $\small\texttt{float clamp}$ | $\small\texttt{0}$ | $\small\texttt{6.10}$ | $\small\texttt{float Clamp}$ | $\small\texttt{0}$ | $\small\texttt{0.44}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int Clamp (int value, int min, int max)}$ | $\small\texttt{0}$ | $\small\texttt{0.50}$ | $\small\texttt{int clamp}$ | $\small\texttt{0}$ | $\small\texttt{2.58}$ | $\small\texttt{int Clamp}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Clamp01 (float value)}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int ClosestPowerOfTwo (int value)}$ | $\small\texttt{0}$ | $\small\texttt{0.51}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{Color CorrelatedColorTemperatureToRGB (float kelvin)}$ | $\small\texttt{0}$ | $\small\texttt{1.65}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Cos (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.47}$ | $\small\texttt{float cos}$ | $\small\texttt{0}$ | $\small\texttt{1.47}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Cosはdouble型)}$ | $\small\texttt{float Cos}$ | $\small\texttt{0}$ | $\small\texttt{0.59}$ | |
$\small\texttt{float DeltaAngle (float current, float target)}$ | $\small\texttt{0}$ | $\small\texttt{3.54}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Exp (float power)}$ | $\small\texttt{0}$ | $\small\texttt{1.80}$ | $\small\texttt{float exp}$ | $\small\texttt{0}$ | $\small\texttt{1.52}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Expはdouble型)}$ | $\small\texttt{float Exp}$ | $\small\texttt{0}$ | $\small\texttt{0.54}$ | |
$\small\texttt{ushort FloatToHalf (float val)}$ | $\small\texttt{0}$ | $\small\texttt{0.52}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Floor (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.46}$ | $\small\texttt{float floor}$ | $\small\texttt{0}$ | $\small\texttt{0.46}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Floorはdouble型)}$ | $\small\texttt{float Floor}$ | $\small\texttt{0}$ | $\small\texttt{0.58}$ | |
$\small\texttt{int FloorToInt (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.46}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float GammaToLinearSpace (float value)}$ | $\small\texttt{0}$ | $\small\texttt{0.68}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float HalfToFloat (ushort val)}$ | $\small\texttt{0}$ | $\small\texttt{0.58}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float InverseLerp (float a, float b, float value)}$ | $\small\texttt{0}$ | $\small\texttt{1.46}$ | $\small\texttt{float unlerp}$ | $\small\texttt{0}$ | $\small\texttt{0.45}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{bool IsPowerOfTwo (int value)}$ | $\small\texttt{0}$ | $\small\texttt{0.48}$ | $\small\texttt{bool ispow2}$ | $\small\texttt{0}$ | $\small\texttt{0.45}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Lerp (float a, float b, float t)}$ | $\small\texttt{0}$ | $\small\texttt{1.36}$ | $\small\texttt{float lerp}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float LerpAngle (float a, float b, float t)}$ | $\small\texttt{0}$ | $\small\texttt{4.49}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float LerpUnclamped (float a, float b, float t)}$ | $\small\texttt{0}$ | $\small\texttt{0.50}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float LinearToGammaSpace (float value)}$ | $\small\texttt{0}$ | $\small\texttt{0.65}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Log (float f, float p)}$ | $\small\texttt{0}$ | $\small\texttt{7.96}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Logはdouble型)}$ | $\small\texttt{float Log}$ | $\small\texttt{0}$ | $\small\texttt{7.26}$ | |
$\small\texttt{float Log (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.56}$ | $\small\texttt{float log}$ | $\small\texttt{0}$ | $\small\texttt{1.45}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Logはdouble型)}$ | $\small\texttt{float Log}$ | $\small\texttt{0}$ | $\small\texttt{0.58}$ | |
$\small\texttt{float Log10 (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.64}$ | $\small\texttt{float log}$ | $\small\texttt{0}$ | $\small\texttt{1.44}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Log10はdouble型)}$ | $\small\texttt{float Log}$ | $\small\texttt{0}$ | $\small\texttt{0.54}$ | |
$\small\texttt{float Max (float a, float b)}$ | $\small\texttt{0}$ | $\small\texttt{0.44}$ | $\small\texttt{float max}$ | $\small\texttt{0}$ | $\small\texttt{2.26}$ | $\small\texttt{float Max}$ | $\small\texttt{0}$ | $\small\texttt{2.49}$ | $\small\texttt{float Max}$ | $\small\texttt{0}$ | $\small\texttt{3.34}$ |
$\small\texttt{float Max (params float[] values)}$ | $\small\texttt{0}$ | $\small\texttt{0.55}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int Max (int a, int b)}$ | $\small\texttt{0}$ | $\small\texttt{0.47}$ | $\small\texttt{int max}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{int Max}$ | $\small\texttt{0}$ | $\small\texttt{0}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int Max (params int[] values)}$ | $\small\texttt{0}$ | $\small\texttt{0.47}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Min (float a, float b)}$ | $\small\texttt{0}$ | $\small\texttt{0.44}$ | $\small\texttt{float min}$ | $\small\texttt{0}$ | $\small\texttt{2.34}$ | $\small\texttt{float Min}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{float Min}$ | $\small\texttt{0}$ | $\small\texttt{1.37}$ |
$\small\texttt{float Min (params float[] values)}$ | $\small\texttt{0}$ | $\small\texttt{0.49}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int Min (int a, int b)}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{int min}$ | $\small\texttt{0}$ | $\small\texttt{0.43}$ | $\small\texttt{int Min}$ | $\small\texttt{0}$ | $\small\texttt{0}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int Min (params int[] values)}$ | $\small\texttt{0}$ | $\small\texttt{0.49}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float MoveTowards (float current, float target, float maxDelta)}$ | $\small\texttt{0}$ | $\small\texttt{3.46}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float MoveTowardsAngle (float current, float target, float maxDelta)}$ | $\small\texttt{0}$ | $\small\texttt{8.45}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{int NextPowerOfTwo (int value)}$ | $\small\texttt{0}$ | $\small\texttt{0.55}$ | $\small\texttt{float ceilpow2}$ | $\small\texttt{0}$ | $\small\texttt{0.45}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float PerlinNoise (float x, float y)}$ | $\small\texttt{0}$ | $\small\texttt{0.67}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float PerlinNoise1D (float x)}$ | $\small\texttt{0}$ | $\small\texttt{0.65}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float PingPong (float t, float length)}$ | $\small\texttt{0}$ | $\small\texttt{5.54}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Pow (float f, float p)}$ | $\small\texttt{0}$ | $\small\texttt{1.71}$ | $\small\texttt{float pow}$ | $\small\texttt{0}$ | $\small\texttt{1.64}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Powはdouble型)}$ | $\small\texttt{float Pow}$ | $\small\texttt{0}$ | $\small\texttt{0.57}$ | |
$\small\texttt{float Repeat (float t, float length)}$ | $\small\texttt{0}$ | $\small\texttt{2.39}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Round (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.46}$ | $\small\texttt{float round}$ | $\small\texttt{0}$ | $\small\texttt{0.45}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Roundはdouble型)}$ | $\small\texttt{float Round}$ | $\small\texttt{0}$ | $\small\texttt{8.81}$ | |
$\small\texttt{int RoundToInt (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.44}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Sign (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.50}$ | $\small\texttt{float sign}$ | $\small\texttt{0}$ | $\small\texttt{0.48}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Signはint型;0.46ms)}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Signはint型)}$ | ||
$\small\texttt{float Sin (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.58}$ | $\small\texttt{float sin}$ | $\small\texttt{0}$ | $\small\texttt{0.87}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Sinはdouble型)}$ | $\small\texttt{float Sin}$ | $\small\texttt{0}$ | $\small\texttt{0.58}$ | |
$\small\texttt{float SmoothDamp (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed, float deltaTime)}$ | $\small\texttt{0}$ | $\small\texttt{4.93}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float SmoothDampAngle (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed, float deltaTime)}$ | $\small\texttt{0}$ | $\small\texttt{9.96}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float SmoothStep (float from, float to, float t)}$ | $\small\texttt{0}$ | $\small\texttt{1.61}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ | $\small\texttt{該当なし}$ | $\small\texttt{}$ | $\small\texttt{}$ |
$\small\texttt{float Sqrt (float f)}$ | $\small\texttt{0}$ | $\small\texttt{0.53}$ | $\small\texttt{float sqrt}$ | $\small\texttt{0}$ | $\small\texttt{0.50}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Sqrtはdouble型)}$ | $\small\texttt{float Aqrt}$ | $\small\texttt{0}$ | $\small\texttt{0.53}$ | |
$\small\texttt{float Tan (float f)}$ | $\small\texttt{0}$ | $\small\texttt{1.66}$ | $\small\texttt{float tan}$ | $\small\texttt{0}$ | $\small\texttt{1.65}$ | $\small\texttt{該当なし}$ | $\small\texttt{(Math.Tanはdouble型)}$ | $\small\texttt{float Tan}$ | $\small\texttt{0}$ | $\small\texttt{0.65}$ |
個人的に驚きだったのは、int型の System.Math.Max
と System.Math.Min
ですね。
これは Profiler
でも、System.Diagnostics.Stopwatch
でも速度0みたいです。
思わず目を疑ってしまいましたが...。
4. おわりに
今回の検証で、各算術関数の内部実装が気になってきたので、また時間があるときにみてみたいと思います。
では、この記事はこの辺で...。
本年もよろしくお願いいたします。
(たぶん、テーブル頑張って設置したせいで、このページ重くなってそう...)