Skip to content

Commit 8982f7f

Browse files
Refactoring
1 parent 7f7faa6 commit 8982f7f

6 files changed

Lines changed: 54 additions & 48 deletions

File tree

benchmarks/Pure.DI.Benchmarks/Tests/ResolveBenchmark.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ namespace Pure.DI.Benchmarks.Tests;
1818
public class ResolveBenchmark
1919
{
2020
private const int MaxItems = 10;
21-
private static readonly Pair<Type, string>[] Pairs;
21+
private static readonly Pair<string>[] Pairs;
2222
private static readonly uint Divisor;
23-
private static readonly int BucketSize;
23+
private static readonly uint BucketSize;
2424
private static readonly Type Key1;
2525
private static readonly Type Key2;
2626
private static readonly Type Key3;
@@ -36,8 +36,8 @@ public class ResolveBenchmark
3636
static ResolveBenchmark()
3737
{
3838
var data = CreatePairs();
39-
Divisor = Buckets<Type, string>.GetDivisor((uint)data.Length);
40-
Pairs = Buckets<Type, string>.Create(
39+
Divisor = Buckets<string>.GetDivisor((uint)data.Length);
40+
Pairs = Buckets<string>.Create(
4141
Divisor,
4242
out BucketSize,
4343
data);
@@ -110,9 +110,9 @@ private string ResolveNoInlining(System.Type type, int index)
110110
throw new System.InvalidOperationException($"Cannot resolve composition root of type {type}.");
111111
}
112112

113-
private static Pair<Type, string>[] CreatePairs() =>
113+
private static Pair<string>[] CreatePairs() =>
114114
Assembly.GetExecutingAssembly().GetTypes()
115115
.Take(MaxItems)
116-
.Select(i => new Pair<Type, string>(i, i.ToString()))
116+
.Select(i => new Pair<string>(i, i.ToString()))
117117
.ToArray();
118118
}

src/Pure.DI.Core/Components/Api.g.cs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,12 +3605,12 @@ public IConfiguration To<T1, T2, T3, T4, T5, T6, T7, T8, T>(Func<T1, T2, T3, T4,
36053605
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
36063606
#endif
36073607
[global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
3608-
internal struct Pair<TKey, TValue>
3608+
internal struct Pair<TValue>
36093609
{
3610-
public readonly TKey Key;
3610+
public readonly global::System.Type Key;
36113611
public readonly TValue Value;
36123612

3613-
public Pair(TKey key, TValue value)
3613+
public Pair(global::System.Type key, TValue value)
36143614
{
36153615
Key = key;
36163616
Value = value;
@@ -3628,39 +3628,43 @@ public override string ToString()
36283628
#if !NET20 && !NET35 && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6 && !NETCOREAPP1_0 && !NETCOREAPP1_1
36293629
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
36303630
#endif
3631-
internal static class Buckets<TKey, TValue>
3631+
internal static class Buckets<TValue>
36323632
{
36333633
[global::System.Runtime.CompilerServices.MethodImpl((global::System.Runtime.CompilerServices.MethodImplOptions)256)]
36343634
public static uint GetDivisor(uint count)
36353635
{
36363636
return count < 2 ? count : count << 1;
36373637
}
36383638

3639-
public static Pair<TKey, TValue>[] Create(
3639+
public static Pair<TValue>[] Create(
36403640
uint divisor,
3641-
out int bucketSize,
3642-
Pair<TKey, TValue>[] pairs)
3641+
out uint bucketSize,
3642+
Pair<TValue>[] pairs)
36433643
{
36443644
bucketSize = 0;
3645-
int[] bucketSizes = new int[divisor];
3646-
for (int i = 0; i < pairs.Length; i++)
3645+
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
3646+
global::System.Span<uint> bucketSizes = divisor < 0x1000 ? stackalloc uint[(int)divisor] : new uint[divisor];
3647+
#else
3648+
var bucketSizes = new uint[divisor];
3649+
#endif
3650+
for (var i = 0; i < pairs.Length; i++)
36473651
{
3648-
int bucket = (int)(((uint)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(pairs[i].Key)) % divisor);
3649-
int size = bucketSizes[bucket] + 1;
3650-
bucketSizes[bucket] = size;
3651-
if (size > bucketSize)
3652+
var bucket = (int)(((uint)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(pairs[i].Key)) % divisor);
3653+
ref var size = ref bucketSizes[bucket];
3654+
if (++size > bucketSize)
36523655
{
36533656
bucketSize = size;
36543657
}
36553658
}
36563659

3657-
Pair<TKey, TValue>[] buckets = new Pair<TKey, TValue>[divisor * bucketSize];
3658-
for (int i = 0; i < pairs.Length; i++)
3660+
var buckets = new Pair<TValue>[divisor * bucketSize];
3661+
for (var i = 0; i < pairs.Length; i++)
36593662
{
3660-
int bucket = (int)(((uint)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(pairs[i].Key)) % divisor);
3661-
var index = bucketSizes[bucket];
3662-
buckets[bucket * bucketSize + bucketSize - index] = pairs[i];
3663-
bucketSizes[bucket] = index - 1;
3663+
var pair = pairs[i];
3664+
var bucket = (int)(((uint)global::System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(pair.Key)) % divisor);
3665+
ref var index = ref bucketSizes[bucket++];
3666+
buckets[bucket * bucketSize - index] = pair;
3667+
index--;
36643668
}
36653669

36663670
return buckets;

src/Pure.DI.Core/Core/Code/Parts/ApiMembersBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ private void CreateObjectResolverMethod(
194194
code.AppendLine($"{methodModifiers} object {methodName}({methodArgs})");
195195
using (code.CreateBlock())
196196
{
197-
var divisor = Buckets<object, object>.GetDivisor((uint)resolvers.Count);
197+
var divisor = Buckets<object>.GetDivisor((uint)resolvers.Count);
198198
if (resolvers.Count > 0)
199199
{
200200
code.AppendLine($"var index = (int)({Names.BucketSizeFieldName} * ((uint){Names.SystemNamespace}Runtime.CompilerServices.RuntimeHelpers.GetHashCode(type) % {divisor}));");

src/Pure.DI.Core/Core/Code/Parts/ResolverFieldsBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public CompositionCode Build(CompositionCode composition)
2121
}
2222

2323
var code = composition.Code;
24-
code.AppendLine($"private readonly static int {Names.BucketSizeFieldName};");
25-
var pairs = $"{Names.SystemNamespace}Type, {Names.IResolverTypeName}<{composition.Source.Source.Name.ClassName}, object>";
24+
code.AppendLine($"private readonly static uint {Names.BucketSizeFieldName};");
25+
var pairs = $"{Names.IResolverTypeName}<{composition.Source.Source.Name.ClassName}, object>";
2626
var pairTypeName = $"{Names.ApiNamespace}Pair<{pairs}>";
2727
code.AppendLine($"private readonly static {pairTypeName}[] {Names.BucketsFieldName};");
2828

src/Pure.DI.Core/Core/Code/Parts/StaticConstructorBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ public CompositionCode Build(CompositionCode composition)
5353
code.AppendLine($"{Names.ResolverClassName}<{typeResolver.Resolve(composition.Source.Source, resolver.Type)}>.{Names.ResolverPropertyName} = val{className};");
5454
}
5555

56-
var divisor = Buckets<object, object>.GetDivisor((uint)resolvers.Count);
57-
var pairs = $"{Names.SystemNamespace}Type, {Names.IResolverTypeName}<{composition.Source.Source.Name.ClassName}, object>";
56+
var divisor = Buckets<object>.GetDivisor((uint)resolvers.Count);
57+
var pairs = $"{Names.IResolverTypeName}<{composition.Source.Source.Name.ClassName}, object>";
5858
var bucketsTypeName = $"{Names.ApiNamespace}Buckets<{pairs}>";
5959
var pairTypeName = $"{Names.ApiNamespace}Pair<{pairs}>";
60-
code.AppendLine($"{Names.BucketsFieldName} = {bucketsTypeName}.{nameof(Buckets<object, object>.Create)}(");
60+
code.AppendLine($"{Names.BucketsFieldName} = {bucketsTypeName}.{nameof(Buckets<object>.Create)}(");
6161
using (code.Indent())
6262
{
6363
code.AppendLine($"{divisor.ToString()},");

tests/Pure.DI.Tests/BucketsTests.cs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ public class BucketsTests
1212
[InlineData(1u)]
1313
[InlineData(2u)]
1414
[InlineData(11u)]
15-
[InlineData(1000u)]
15+
[InlineData(100u)]
1616
internal void ShouldGetValues(uint count)
1717
{
1818
// Given
1919
var data = CreatePairs(count);
20-
var divisor = Buckets<string, int>.GetDivisor(count);
20+
var divisor = Buckets<int>.GetDivisor(count);
2121

2222
// When
23-
var pairs = Buckets<string, int>.Create(
23+
var pairs = Buckets<int>.Create(
2424
divisor,
2525
out var bucketSize,
2626
data);
@@ -37,15 +37,17 @@ internal void ShouldGetValues(uint count)
3737
}
3838
}
3939

40-
private static Pair<string, int>[] CreatePairs(uint count) =>
41-
Enumerable.Range(0, (int)count)
42-
.Select(i => new Pair<string, int>((100 + i).ToString(), i))
43-
.ToArray();
40+
private static Pair<int>[] CreatePairs(uint count) => AppDomain.CurrentDomain.GetAssemblies()
41+
.SelectMany(i => i.ExportedTypes)
42+
.Distinct()
43+
.Take((int)count)
44+
.Select((i, index) => new Pair<int>(i, index))
45+
.ToArray();
4446

4547
private static TValue Get<TKey, TValue>(
46-
Pair<TKey, TValue>[] pairs,
48+
Pair<TValue>[] pairs,
4749
uint divisor,
48-
int bucketSize,
50+
uint bucketSize,
4951
TKey key)
5052
{
5153
int index = (int)(bucketSize * ((uint)RuntimeHelpers.GetHashCode(key) % divisor));
@@ -55,7 +57,7 @@ private static TValue Get<TKey, TValue>(
5557
return pair.Value;
5658
}
5759

58-
int maxIndex = index + bucketSize;
60+
var maxIndex = index + bucketSize;
5961
for (int i = index + 1; i < maxIndex; i++)
6062
{
6163
pair = ref pairs[i];
@@ -72,16 +74,16 @@ private static TValue Get<TKey, TValue>(
7274
public void ShouldSupportTypeKey()
7375
{
7476
// Given
75-
var divisor = Buckets<Type, int>.GetDivisor(5);
76-
var pairs = Buckets<Type, int>.Create(
77+
var divisor = Buckets<int>.GetDivisor(5);
78+
var pairs = Buckets<int>.Create(
7779
divisor,
7880
out var bucketSize,
7981
[
80-
new Pair<Type, int>(typeof(string), 1),
81-
new Pair<Type, int>(typeof(int), 2),
82-
new Pair<Type, int>(typeof(double), 3),
83-
new Pair<Type, int>(typeof(float), 4),
84-
new Pair<Type, int>(typeof(char), 5)
82+
new Pair<int>(typeof(string), 1),
83+
new Pair<int>(typeof(int), 2),
84+
new Pair<int>(typeof(double), 3),
85+
new Pair<int>(typeof(float), 4),
86+
new Pair<int>(typeof(char), 5)
8587
]
8688
);
8789

0 commit comments

Comments
 (0)