Skip to content

Commit 63de39c

Browse files
committed
v1.3.0 Release.
1 parent 96b8fce commit 63de39c

13 files changed

Lines changed: 237 additions & 22 deletions

README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ Zero-allocation Boxing is achieved by pooling Boxing objects in advance and reus
1818
#### Result
1919
| Process | Time |
2020
| ---- | ---- |
21-
| Boxing_Legacy | 34.47214 ms |
22-
| Boxing_Pool | 17.515775 ms |
23-
| Boxing_StructOnlyPool | 17.239465 ms |
24-
| Boxing_ConcurrentPool | 17.70384 ms |
25-
| Boxing_ConcurrentStructOnlyPool | 15.53006 ms |
21+
| Boxing_Legacy | 31.004235 ms |
22+
| Boxing_Pool | 15.1678 ms |
23+
| Boxing_StructOnlyPool | 15.358 ms |
24+
| Boxing_ConcurrentPool | 15.4086 ms |
25+
| Boxing_ConcurrentStructOnlyPool | 15.39855 ms |
26+
| Boxing_ThreadStaticPool | 15.19975 ms |
27+
| Boxing_ThreadStaticStructOnlyPool | 15.3461 ms |
2628

2729
Using BoxingPool, the performance improvement is about 2x.
2830
Also, allocation has been reduced to zero, and memory performance has been improved.
@@ -82,11 +84,13 @@ using (new Measure("Boxing_Pool", log))
8284
#### Result
8385
| Process | Mono | IL2CPP |
8486
| ---- | ---- | ---- |
85-
| Boxing_Legacy | 57.6889 ms | 35.61328 ms |
86-
| Boxing_Pool | 8.582088 ms | 2.003906 ms |
87-
| Boxing_StructOnlyPool | 8.450382 ms | 1.962891 ms |
88-
| Boxing_ConcurrentPool | 9.024681 ms | 3.015625 ms |
89-
| Boxing_ConcurrentStructOnlyPool | 8.934082 ms | 2.90625 ms |
87+
| Boxing_Legacy | 52.86654 ms | 41.43652 ms |
88+
| Boxing_Pool | 9.189175 ms | 2.425781 ms |
89+
| Boxing_StructOnlyPool | 9.142063 ms | 2.452148 ms |
90+
| Boxing_ConcurrentPool | 9.591019 ms | 3.321289 ms |
91+
| Boxing_ConcurrentStructOnlyPool | 9.610249 ms | 3.245117 ms |
92+
| Boxing_ThreadStaticPool | 9.15694 ms | 2.49707 ms |
93+
| Boxing_ThreadStaticStructOnlyPool | 9.292259 ms | 2.520508 ms |
9094

9195
We saw a performance improvement of about 17x.
9296

README_ja.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ Box化オブジェクトを事前にPoolしておき、必要なときに再利
1717
#### 結果
1818
| 実行処理 | 処理時間 |
1919
| ---- | ---- |
20-
| Boxing_Legacy | 34.47214 ms |
21-
| Boxing_Pool | 17.515775 ms |
22-
| Boxing_StructOnlyPool | 17.239465 ms |
23-
| Boxing_ConcurrentPool | 17.70384 ms |
24-
| Boxing_ConcurrentStructOnlyPool | 15.53006 ms |
20+
| Boxing_Legacy | 31.004235 ms |
21+
| Boxing_Pool | 15.1678 ms |
22+
| Boxing_StructOnlyPool | 15.358 ms |
23+
| Boxing_ConcurrentPool | 15.4086 ms |
24+
| Boxing_ConcurrentStructOnlyPool | 15.39855 ms |
25+
| Boxing_ThreadStaticPool | 15.19975 ms |
26+
| Boxing_ThreadStaticStructOnlyPool | 15.3461 ms |
2527

2628
BoxingPoolを使うことで2倍程度のパフォーマンス改善が見られます。
2729
またアロケーションもゼロになり、メモリパフォーマンスも向上しています。
@@ -81,11 +83,13 @@ using (new Measure("Boxing_Pool", log))
8183
#### 結果
8284
| 実行処理 | Mono | IL2CPP |
8385
| ---- | ---- | ---- |
84-
| Boxing_Legacy | 57.6889 ms | 35.61328 ms |
85-
| Boxing_Pool | 8.582088 ms | 2.003906 ms |
86-
| Boxing_StructOnlyPool | 8.450382 ms | 1.962891 ms |
87-
| Boxing_ConcurrentPool | 9.024681 ms | 3.015625 ms |
88-
| Boxing_ConcurrentStructOnlyPool | 8.934082 ms | 2.90625 ms |
86+
| Boxing_Legacy | 52.86654 ms | 41.43652 ms |
87+
| Boxing_Pool | 9.189175 ms | 2.425781 ms |
88+
| Boxing_StructOnlyPool | 9.142063 ms | 2.452148 ms |
89+
| Boxing_ConcurrentPool | 9.591019 ms | 3.321289 ms |
90+
| Boxing_ConcurrentStructOnlyPool | 9.610249 ms | 3.245117 ms |
91+
| Boxing_ThreadStaticPool | 9.15694 ms | 2.49707 ms |
92+
| Boxing_ThreadStaticStructOnlyPool | 9.292259 ms | 2.520508 ms |
8993

9094
17倍程度のパフォーマンス改善が見られました。
9195

-1 KB
Binary file not shown.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.assembly Katuusagi.BoxingPool.Utils { }
2+
.assembly extern mscorlib { }
3+
4+
.module Katuusagi.BoxingPool.Utils.dll
5+
6+
.class public auto ansi abstract sealed beforefieldinit Katuusagi.Pool.Utils.BoxingUtils
7+
extends [mscorlib]System.Object
8+
{
9+
.method public hidebysig static !!T& Unbox<T>(object obj) cil managed aggressiveinlining
10+
{
11+
ldarg.0
12+
unbox !!T
13+
ret
14+
}
15+
16+
}

packages/Plugins/Katuusagi.BoxingPool.Utils.il.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/Runtime/BoxingPool.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ namespace Katuusagi.Pool
55
{
66
public static class BoxingPool<T>
77
{
8+
public readonly struct ReadOnlyHandler
9+
{
10+
private readonly object _obj;
11+
12+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
13+
public ReadOnlyHandler(object obj)
14+
{
15+
_obj = obj;
16+
}
17+
18+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
19+
public void Dispose()
20+
{
21+
Return(_obj);
22+
}
23+
}
24+
825
public readonly ref struct GetHandler
926
{
1027
private readonly object _obj;
@@ -20,6 +37,11 @@ public void Dispose()
2037
{
2138
Return(_obj);
2239
}
40+
41+
public static implicit operator ReadOnlyHandler(GetHandler obj)
42+
{
43+
return new ReadOnlyHandler(obj._obj);
44+
}
2345
}
2446

2547
public static readonly bool IsStruct;

packages/Runtime/ConcurrentBoxingPool.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ namespace Katuusagi.Pool
55
{
66
public static class ConcurrentBoxingPool<T>
77
{
8+
public readonly struct ReadOnlyHandler
9+
{
10+
private readonly object _obj;
11+
12+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
13+
public ReadOnlyHandler(object obj)
14+
{
15+
_obj = obj;
16+
}
17+
18+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
19+
public void Dispose()
20+
{
21+
Return(_obj);
22+
}
23+
}
24+
825
public readonly ref struct GetHandler
926
{
1027
private readonly object _obj;
@@ -20,6 +37,11 @@ public void Dispose()
2037
{
2138
Return(_obj);
2239
}
40+
41+
public static implicit operator ReadOnlyHandler(GetHandler obj)
42+
{
43+
return new ReadOnlyHandler(obj._obj);
44+
}
2345
}
2446

2547
private static readonly bool IsStruct;

packages/Runtime/ConcurrentStructOnlyBoxingPool.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ namespace Katuusagi.Pool
66
public static class ConcurrentStructOnlyBoxingPool<T>
77
where T : struct
88
{
9+
public readonly struct ReadOnlyHandler
10+
{
11+
private readonly object _obj;
12+
13+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
14+
public ReadOnlyHandler(object obj)
15+
{
16+
_obj = obj;
17+
}
18+
19+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
20+
public void Dispose()
21+
{
22+
Return(_obj);
23+
}
24+
}
25+
926
public readonly ref struct GetHandler
1027
{
1128
private readonly object _obj;
@@ -21,6 +38,11 @@ public void Dispose()
2138
{
2239
Return(_obj);
2340
}
41+
42+
public static implicit operator ReadOnlyHandler(GetHandler obj)
43+
{
44+
return new ReadOnlyHandler(obj._obj);
45+
}
2446
}
2547

2648
static ConcurrentStructOnlyBoxingPool()

packages/Runtime/StructOnlyBoxingPool.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@ namespace Katuusagi.Pool
66
public static class StructOnlyBoxingPool<T>
77
where T : struct
88
{
9+
public readonly struct ReadOnlyHandler
10+
{
11+
private readonly object _obj;
12+
13+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
14+
public ReadOnlyHandler(object obj)
15+
{
16+
_obj = obj;
17+
}
18+
19+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
20+
public void Dispose()
21+
{
22+
Return(_obj);
23+
}
24+
}
25+
926
public readonly ref struct GetHandler
1027
{
1128
private readonly object _obj;
@@ -21,6 +38,11 @@ public void Dispose()
2138
{
2239
Return(_obj);
2340
}
41+
42+
public static implicit operator ReadOnlyHandler(GetHandler obj)
43+
{
44+
return new ReadOnlyHandler(obj._obj);
45+
}
2446
}
2547

2648
public static void MakeCache(int minCount)

packages/Runtime/ThreadStaticBoxingPool.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ namespace Katuusagi.Pool
55
{
66
public static class ThreadStaticBoxingPool<T>
77
{
8+
public readonly struct ReadOnlyHandler
9+
{
10+
private readonly object _obj;
11+
12+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
13+
public ReadOnlyHandler(object obj)
14+
{
15+
_obj = obj;
16+
}
17+
18+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
19+
public void Dispose()
20+
{
21+
Return(_obj);
22+
}
23+
}
24+
825
public readonly ref struct GetHandler
926
{
1027
private readonly object _obj;
@@ -20,6 +37,11 @@ public void Dispose()
2037
{
2138
Return(_obj);
2239
}
40+
41+
public static implicit operator ReadOnlyHandler(GetHandler obj)
42+
{
43+
return new ReadOnlyHandler(obj._obj);
44+
}
2345
}
2446

2547
public static readonly bool IsStruct;

0 commit comments

Comments
 (0)