パフォーマンス

データフローで値の受け渡しをする場合、ボックス化でのGC Allocなどによりパフォーマンスが低下する恐れがあります。

ボックス化によるパフォーマンス低下が起こりえる条件は以下の通りです。

  • 受け渡すデータの型が値型。
  • ValueMediatorに登録されていない型。
  • OutputSlotAnyやOutputSlotTypableなどの汎用的なスロットを介して受け渡している。
    (組み込みスクリプトのList関連など型指定するタイプのスクリプトも該当)
  • object版入出力メソッドを使用している。
  • 以下の組み込みスクリプトを使用している場合、object型を直接取り扱っているためボックス化の回避不可

型固有のスロットクラスを使用する

例えばint型のみの使用が確定している場合にはOutputSlotIntを使用するなど、不必要な汎用タイプのスロット使用は避けてください。

ValueMediatorによるボックス化回避

OutputSlotAnyやOutputSlotTypableなどを使用する場合、ValueMediatorを使用することでボックス化が削減できます。

ValueMediatorの登録

ValueMediatorに値型を登録しておくことで、ボックス化が削減できます。

例として、Arbor.Example名前空間にあるDataFlowExampleData構造体をValueMediatorに登録するコードは以下のようになります。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
using Arbor.ValueFlow;

static class ExampleRegisterValueMediator
{
	[ValueMediatorInitializeOnLoadMethod]
	static void OnRegisterValueMeditor()
	{
		ValueMediator.Register<Arbor.Example.DataFlowExampleData>();
	}
}

値の入出力にジェネリック版メソッドを使用する

OutputSlotAny.SetValue(object value)などのobject版メソッドを使用するとその時点でボックス化してしまうため、代わりにSetValue<T>(T value)などのジェネリックメソッドを使用してください。

出力スロット側の例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
using UnityEngine;
using Arbor;

public class ExampleSetDataFlow : Calculator
{
	[SlotType(typeof(Arbor.Example.DataFlowExampleData))]
	public OutputSlotAny output = new OutputSlotAny();

	public override void OnCalculate()
	{
		var data = new Arbor.Example.DataFlowExampleData()
		{
			stringValue = "abcde",
			intValue = 12345,
		};
		output.SetValue<Arbor.Example.DataFlowExampleData>(data);
	}
}

入力スロット側の例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
using UnityEngine;
using Arbor;

[AddComponentMenu("")]
public class ExampleGetDataFlow : StateBehaviour
{
	[SlotType(typeof(Arbor.Example.DataFlowExampleData))]
	public InputSlotAny input = new InputSlotAny();

	// Use this for enter state
	public override void OnStateBegin()
	{
		Arbor.Example.DataFlowExampleData data = new Arbor.Example.DataFlowExampleData();
		if (input.GetValue<Arbor.Example.DataFlowExampleData>(ref data))
		{
			Debug.LogFormat("stringValue : {0}\nintValue : {1}", data.stringValue, data.intValue.ToString());
		}
	}
}

ValueMediatorに予め登録済みの型

  • sbyte
  • byte
  • short
  • ushort
  • int
  • uint
  • long
  • ulong
  • char
  • float
  • double
  • decimal
  • UnityEngine.Vector2
  • UnityEngine.Vector3
  • UnityEngine.Vector4
  • UnityEngine.Quaternion
  • UnityEngine.Rect
  • UnityEngine.Bounds
  • UnityEngine.Color
  • UnityEngine.Color32
  • UnityEngine.Matrix4x4
  • UnityEngine.Vector2Int
  • UnityEngine.Vector3Int
  • UnityEngine.RectInt
  • UnityEngine.BoundsInt