Last active
January 17, 2019 05:37
-
-
Save YuukiARIA/ac86a53b9a8a6aff05a5aea0bd8043fa to your computer and use it in GitHub Desktop.
Unity GC Alloc Examples (Unity2018.3.0f2 PlayMode Test)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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