CosやSinをテーブル引きにする効果
-
-
- -
-
追記 2017/2/8 23:20
各所からツッコミを受けました。
テーブル引きの恩恵を受けるようなコードは、現在の実践環境ではあまりなく、普通に関数を使ったほうが有利というのが説が多いです。
以下のテストはキャッシュが効きやすい状態のテストなので一応、テーブル引きが勝っていますが、結構特殊な状況です。
ほんとうは、ちゃんと実際のゲーム中で計測するべきなんですけど、すいませんm(_ _)m
速度的なメリットは怪しいけどテーブル引きのメリットは、
通信量を落とせるとか(角度をfloatの32bitじゃなく8bitとか16bitで持ちたいとき)
値が実行環境に依存しないとか
というメリットがあると言われ、自分も納得しました。
-
-
- -
-
CosやSinをテーブル引きにする効果
ゲーム制作において、高速化のためにCosやSinといった関数をテーブル引きにするというのは、よくある話である。
自分のゲーム制作環境でも少しでも処理を軽くするためにテーブル引きSin,Cosを作ってみようかと思ったのだけれど、そもそもどれぐらい処理の高速化が見込めるのか、Unity上で試してみた。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestScript : MonoBehaviour { public int loopCount = 10000000; System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch(); public int tableSize = 360; public const float PI2 = Mathf.PI * 2.0f; float[] cosTable; void Start () { cosTable = new float[ tableSize ]; for( int i = 0; i < tableSize; ++i ) { float theta = (float)i / tableSize * PI2; cosTable[i] = Mathf.Cos( theta ); } } [ContextMenu("Test Mathf")] void TestMathf () { stopWatch.Reset(); stopWatch.Start(); float sum = 0.0f; for( int i = 0; i < loopCount; ++i ) { sum += Mathf.Cos( (float)i ); } stopWatch.Stop(); Debug.Log( "time : " + stopWatch.Elapsed + " sum, " + sum ); } [ContextMenu("Test Cos Table")] void TestCosTable () { stopWatch.Reset(); stopWatch.Start(); float sum = 0.0f; for( int i = 0; i < loopCount; ++i ) { sum += getCosFromTable( (float)i ); } stopWatch.Stop(); Debug.Log( "time : " + stopWatch.Elapsed + " sum, " + sum ); } int getCosTableIndex ( float theta ) { return (int)( theta / PI2 * tableSize ) % tableSize; } float getCosFromTable ( float theta ) { int index = getCosTableIndex( theta ); return cosTable[ index ]; } }
1000万回、Cosを計算して加算した結果、自分のMacbook Pro上で、Mathf.Cosは0.552秒、tableを使ったCosは0.453秒とTableを使ったほうが20%ぐらい高速だった。
もっと差が出るかと思っていたのだけど、そうでもなかった。
tableを使った方は精度がイマイチなのでご利用は計画的に。