nirasan's tech blog

趣味や仕事の覚え書きです。Linux, Perl, PHP, Ruby, Javascript, Android, Cocos2d-x, Unity などに興味があります。

Unity で拡張メソッドと静的コンストラクタを使った enum 文字列変換の高速化

はじめに

宣言

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace MyConst {

	public enum PREF
	{
		MAX_LIFE,
		MAX_BOMB,
		CURRENT_COIN,
	}

	public class Const {

		public static int DEFAULT_LIFE = 3;
		public static int DEFAULT_BOMB = 3;

		public static List<string> PREF_STRINGS;

		static Const() {
			PREF_STRINGS = new List<string> ();
			foreach (PREF p in Enum.GetValues(typeof(PREF))) {
				PREF_STRINGS.Add (p.ToString());
			}
		}
	}

	public static class Extentions {

		public static string ToStringExt(this MyConst.PREF p) {
			return Const.PREF_STRINGS[(int)p];
		}

		public static string ToStringExt(this MyConst.PREF p, string s) {
			return string.Format ("{0}_{1}", p.ToStringExt(), s);
		}
	}
}

使用例

using MyConst;
string str1 = PREF.MAX_LIFE.ToStringExt (); //=> "MAX_LIFE"
string str2 = PREF.MAX_LIFE.ToStringExt ("FOO"); //=> "MAX_LIFE_FOO"

速度比較

  • Unity Test Tools を使って ToString と ToStringExt の速度比較

コード

  • 任意のフォルダー以下に "Editor" フォルダーを作成し、任意の名前で下記のファイルを作成
  • メニューの "Unity Test Tools" から "Unit Test Runner" でテストビューを表示して実行
using UnityEngine;
using System.Collections;
using NUnit.Framework;
using MyConst;
using System.Diagnostics;

[TestFixture]
[Category("MyConst")]
public class MyConstTest {

	[Test]
	public void MyConstEnumToStringTest () {
	
		Stopwatch sw1 = new Stopwatch();
		sw1.Start();
		for (int i = 0; i < 100000; i++)
		{
			string s = PREF.MAX_LIFE.ToStringExt ();
		}
		sw1.Stop();
		long millisec1 = sw1.ElapsedMilliseconds;

		Stopwatch sw2 = new Stopwatch();
		sw2.Start();
		for (int i = 0; i < 100000; i++)
		{
			string s = PREF.MAX_LIFE.ToString ();
		}
		sw2.Stop();
		long millisec2 = sw2.ElapsedMilliseconds;

		UnityEngine.Debug.Log ("ToStringExt : " + millisec1.ToString() + "ミリ秒");
		UnityEngine.Debug.Log ("ToString : " + millisec2.ToString() + "ミリ秒");

		Assert.That (millisec1 < millisec2);
	}
}

結果

  • 10回程度実行した結果、ToString より ToStringExt のほうが最大300倍ほど速い
    • ToStringExt: 1〜3ミリ秒
    • ToString: 260〜300ミリ秒