Skip to content

Instantly share code, notes, and snippets.

@YuukiARIA
Last active January 17, 2019 05:37
Show Gist options
  • Save YuukiARIA/ac86a53b9a8a6aff05a5aea0bd8043fa to your computer and use it in GitHub Desktop.
Save YuukiARIA/ac86a53b9a8a6aff05a5aea0bd8043fa to your computer and use it in GitHub Desktop.
Unity GC Alloc Examples (Unity2018.3.0f2 PlayMode Test)
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.TestTools.Constraints;
using Is = UnityEngine.TestTools.Constraints.Is;
enum Language
{
Ruby, CSharp, Elixir
}
class SampleClass
{
public int X;
}
struct SampleStruct
{
public int X;
}
interface ISampleA
{
void SampleA();
}
interface ISampleB
{
void SampleB();
}
struct SampleA : ISampleA
{
void ISampleA.SampleA()
{
}
}
struct SampleB : ISampleB
{
void ISampleB.SampleB()
{
}
}
static class SampleExtension
{
public static void InvokeSampleA(this ISampleA x)
{
x.SampleA();
}
public static void InvokeSampleB<T>(this T x) where T : ISampleB
{
x.SampleB();
}
}
public class SimpleTest
{
[Test(Description = "enumをEqualsで比較")]
public void Test1()
{
Assert.That(() =>
{
if (Language.Ruby.Equals(Language.Elixir))
{
}
}, Is.AllocatingGCMemory());
}
[Test(Description = "enumを==で比較")]
public void Test2()
{
Assert.That(() =>
{
if (Language.Ruby == Language.Elixir)
{
}
}, Is.Not.AllocatingGCMemory());
}
private static readonly string CSharp = "CSharp";
private static readonly string Ruby = "Ruby";
[Test(Description = "enumキーのDictionary")]
public void Test_EnumKeyDictionary_Add()
{
var dic = new Dictionary<Language, string>();
Assert.That(() => dic.Add(Language.CSharp, CSharp), Is.AllocatingGCMemory());
Assert.That(() => dic.Add(Language.Ruby, Ruby), Is.Not.AllocatingGCMemory());
}
[Test(Description = "intキーのDictionaryをenumをキャストして使う")]
public void Test_EnumKeyDictionary_Add_Cast()
{
var dic = new Dictionary<int, string>();
Assert.That(() => dic.Add((int)Language.CSharp, CSharp), Is.AllocatingGCMemory());
Assert.That(() => dic.Add((int)Language.Ruby, Ruby), Is.Not.AllocatingGCMemory());
}
private const string ConstString = "";
private static readonly string StaticReadOnlyString = "";
[Test(Description = "const stringとstatic readonly string")]
public void Test_ConstStringAndStaticReadOnlyString()
{
Assert.That(() =>
{
var s = ConstString;
}, Is.AllocatingGCMemory());
Assert.That(() =>
{
var s = StaticReadOnlyString;
}, Is.Not.AllocatingGCMemory());
}
[Test(Description = "配列")]
public void Test_AllocateArray()
{
Assert.That(() =>
{
var array = new byte[10];
}, Is.AllocatingGCMemory());
}
[Test(Description = "クラスの確保")]
public void Test_AllocateClass()
{
Assert.That(() =>
{
var value = new SampleClass();
}, Is.AllocatingGCMemory());
}
[Test(Description = "構造体の確保")]
public void Test_AllocateStruct()
{
Assert.That(() =>
{
var value = new SampleStruct();
}, Is.Not.AllocatingGCMemory());
}
[Test(Description = "値型のボクシング")]
public void Test_BoxingValueType()
{
Assert.That(() =>
{
object value = 10;
}, Is.AllocatingGCMemory());
}
private void Method1(object x) { }
[Test(Description = "object型引数によるボクシング")]
public void Test_BoxingObjectArgument()
{
Assert.That(() =>
{
Method1(10);
}, Is.AllocatingGCMemory());
}
[Test(Description = "nullableによるボクシング")]
public void Test_BoxingNullable()
{
Assert.That(() =>
{
int? x = 10;
}, Is.AllocatingGCMemory());
}
[Test(Description = "文字列補完(=string.Format)によるボクシング")]
public void Test_Boxing_StringInterpolation()
{
Assert.That(() =>
{
var s = $"{1}";
}, Is.AllocatingGCMemory());
}
private T CreateByDefault<T>() where T : struct
{
return default;
}
private T CreateByNew<T>() where T : struct
{
return new T();
}
[Test(Description = "ジェネリクス経由での構造体の値生成")]
public void Test_InstantiateGenericValueType()
{
Assert.That(() =>
{
CreateByDefault<SampleStruct>();
}, Is.Not.AllocatingGCMemory());
Assert.That(() =>
{
CreateByNew<SampleStruct>();
}, Is.AllocatingGCMemory());
}
[Test(Description = "interfaceと拡張メソッドによるボクシング")]
public void Test_ExtensionMethodForInterfaceBoxing()
{
Assert.That(() =>
{
new SampleA().InvokeSampleA();
}, Is.AllocatingGCMemory());
Assert.That(() =>
{
new SampleB().InvokeSampleB();
}, Is.Not.AllocatingGCMemory());
}
[Test(Description = "Linq")]
public void Test_Linq()
{
var array = new int[] { 0, 1, 2, 3, 4, 5, 6 };
Assert.That(() =>
{
foreach (var x in array.Where(x => x % 2 == 0))
{
}
}, Is.AllocatingGCMemory());
Assert.That(() =>
{
foreach (var x in array)
{
if (x % 2 == 0)
{
}
}
}, Is.Not.AllocatingGCMemory());
}
[Test(Description = "配列に対するforeachによるIEnumerable.GetEnumerator()呼び出し")]
public void Test_ForEachIEnumerable()
{
IEnumerable<int> array = new int[] { 0, 1, 2, 3, 4, 5, 6 };
Assert.That(() =>
{
foreach (var x in array)
{
}
}, Is.AllocatingGCMemory());
}
private void InstanceMethod()
{
}
private static void StaticMethod()
{
}
private static void Invoke(Action action)
{
action();
}
private void InvokeLambdaInstance()
{
Invoke(() => InstanceMethod());
}
private void InvokeLambdaStatic()
{
Invoke(() => StaticMethod());
}
[Test(Description = "デリゲートとラムダ式")]
public void Test_CreateDelegate_CallTwice()
{
Assert.That(() => Invoke(InstanceMethod), Is.AllocatingGCMemory());
Assert.That(() => Invoke(InstanceMethod), Is.AllocatingGCMemory());
Assert.That(() => Invoke(StaticMethod), Is.AllocatingGCMemory());
Assert.That(() => Invoke(StaticMethod), Is.AllocatingGCMemory());
Assert.That(() => InvokeLambdaInstance(), Is.AllocatingGCMemory());
Assert.That(() => InvokeLambdaInstance(), Is.AllocatingGCMemory());
Assert.That(() => InvokeLambdaStatic(), Is.AllocatingGCMemory());
Assert.That(() => InvokeLambdaStatic(), Is.Not.AllocatingGCMemory());
}
[Test(Description = "LinkedListNode")]
public void Test_LinkedListNode()
{
var list = new LinkedList<int>();
Assert.That(() => list.AddLast(1), Is.AllocatingGCMemory());
}
[Test(Description = "List Capacity")]
public void Test_ListCapacity()
{
var list = new List<int>(4);
Assert.That(() => list.Add(1), Is.Not.AllocatingGCMemory());
Assert.That(() => list.Add(2), Is.Not.AllocatingGCMemory());
Assert.That(() => list.Add(3), Is.Not.AllocatingGCMemory());
Assert.That(() => list.Add(4), Is.Not.AllocatingGCMemory());
Assert.That(() => list.Add(5), Is.AllocatingGCMemory());
}
private void MethodParams(params int[] args)
{
}
[Test(Description = "params")]
public void Test_ParamsCausesArrayAllocation()
{
Assert.That(() => MethodParams(1, 2, 3), Is.AllocatingGCMemory());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment