Use interface for AddRange optimizations
This commit is contained in:
1 parent
1d4d5e9217
commit
b571a2df59
5 files changed
+35
-134
No files matched your search
@@ -0,0 +1,9 @@
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal interface IAddRangeProvider<T>
|
||||
{
|
||||
void AddRangeTo(RecyclableList<T> list);
|
||||
void AddRangeTo(RecyclableLongList<T> list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ using Recyclable.Collections.Pools;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal sealed class RecyclableDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDisposable
|
||||
internal sealed class RecyclableDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IDisposable, IAddRangeProvider<KeyValuePair<TKey, TValue>>
|
||||
where TKey : notnull
|
||||
{
|
||||
internal static readonly bool _needsClearing = !typeof(TKey).IsValueType || !typeof(TValue).IsValueType;
|
||||
@@ -401,5 +401,15 @@ namespace Recyclable.Collections
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void IAddRangeProvider<KeyValuePair<TKey, TValue>>.AddRangeTo(RecyclableList<KeyValuePair<TKey, TValue>> list)
|
||||
{
|
||||
zRecyclableListAddRange.AddRange(list, this);
|
||||
}
|
||||
|
||||
void IAddRangeProvider<KeyValuePair<TKey, TValue>>.AddRangeTo(RecyclableLongList<KeyValuePair<TKey, TValue>> list)
|
||||
{
|
||||
zRecyclableLongListAddRange.AddRange(list, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,11 @@
|
||||
using System.Collections;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
public static class zRecyclableListAddRange
|
||||
{
|
||||
private static class AddRangeHelper<T>
|
||||
{
|
||||
internal static readonly Type? DictionaryType;
|
||||
internal static readonly Type? SortedListType;
|
||||
internal static readonly Action<RecyclableList<T>, IEnumerable<T>>? DictionaryAdder;
|
||||
internal static readonly Action<RecyclableList<T>, IEnumerable<T>>? SortedListAdder;
|
||||
|
||||
static AddRangeHelper()
|
||||
{
|
||||
var itemType = typeof(T);
|
||||
if (itemType.IsGenericType)
|
||||
{
|
||||
var genericDefinition = itemType.GetGenericTypeDefinition();
|
||||
if (genericDefinition == typeof(KeyValuePair<,>))
|
||||
{
|
||||
var args = itemType.GetGenericArguments();
|
||||
DictionaryType = typeof(RecyclableDictionary<,>).MakeGenericType(args);
|
||||
|
||||
var listType = typeof(RecyclableList<>).MakeGenericType(itemType);
|
||||
var method = typeof(zRecyclableListAddRange).GetMethod(
|
||||
nameof(AddRange),
|
||||
BindingFlags.NonPublic | BindingFlags.Static,
|
||||
null,
|
||||
new[] { listType, DictionaryType },
|
||||
null)!.MakeGenericMethod(args);
|
||||
|
||||
var listParam = Expression.Parameter(typeof(RecyclableList<T>), "list");
|
||||
var itemsParam = Expression.Parameter(typeof(IEnumerable<T>), "items");
|
||||
var call = Expression.Call(method,
|
||||
Expression.Convert(listParam, listType),
|
||||
Expression.Convert(itemsParam, DictionaryType));
|
||||
|
||||
DictionaryAdder = Expression.Lambda<Action<RecyclableList<T>, IEnumerable<T>>>(call, listParam, itemsParam).Compile();
|
||||
}
|
||||
else if (genericDefinition == typeof(ValueTuple<,>))
|
||||
{
|
||||
var args = itemType.GetGenericArguments();
|
||||
SortedListType = typeof(RecyclableSortedList<,>).MakeGenericType(args);
|
||||
|
||||
var listType = typeof(RecyclableList<>).MakeGenericType(itemType);
|
||||
var method = typeof(zRecyclableListAddRange).GetMethod(
|
||||
nameof(AddRange),
|
||||
BindingFlags.NonPublic | BindingFlags.Static,
|
||||
null,
|
||||
new[] { listType, SortedListType },
|
||||
null)!.MakeGenericMethod(args);
|
||||
|
||||
var listParam = Expression.Parameter(typeof(RecyclableList<T>), "list");
|
||||
var itemsParam = Expression.Parameter(typeof(IEnumerable<T>), "items");
|
||||
var call = Expression.Call(method,
|
||||
Expression.Convert(listParam, listType),
|
||||
Expression.Convert(itemsParam, SortedListType));
|
||||
|
||||
SortedListAdder = Expression.Lambda<Action<RecyclableList<T>, IEnumerable<T>>>(call, listParam, itemsParam).Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddRangeEnumerated<T>(this RecyclableList<T> list, IEnumerable<T> items, int growByCount)
|
||||
{
|
||||
@@ -638,13 +578,9 @@ namespace Recyclable.Collections
|
||||
{
|
||||
AddRange(list, sourceQueue);
|
||||
}
|
||||
else if (AddRangeHelper<T>.DictionaryAdder != null && AddRangeHelper<T>.DictionaryType!.IsInstanceOfType(items))
|
||||
else if (items is IAddRangeProvider<T> provider)
|
||||
{
|
||||
AddRangeHelper<T>.DictionaryAdder!(list, items);
|
||||
}
|
||||
else if (AddRangeHelper<T>.SortedListAdder != null && AddRangeHelper<T>.SortedListType!.IsInstanceOfType(items))
|
||||
{
|
||||
AddRangeHelper<T>.SortedListAdder!(list, items);
|
||||
provider.AddRangeTo(list);
|
||||
}
|
||||
else if (items is IReadOnlyList<T> sourceIReadOnlyList)
|
||||
{
|
||||
|
||||
@@ -1,72 +1,12 @@
|
||||
using System.Collections;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Recyclable.Collections.Pools;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
public static class zRecyclableLongListAddRange
|
||||
{
|
||||
private static class AddRangeHelper<T>
|
||||
{
|
||||
internal static readonly Type? DictionaryType;
|
||||
internal static readonly Type? SortedListType;
|
||||
internal static readonly Action<RecyclableLongList<T>, IEnumerable<T>>? DictionaryAdder;
|
||||
internal static readonly Action<RecyclableLongList<T>, IEnumerable<T>>? SortedListAdder;
|
||||
|
||||
static AddRangeHelper()
|
||||
{
|
||||
var itemType = typeof(T);
|
||||
if (itemType.IsGenericType)
|
||||
{
|
||||
var genericDefinition = itemType.GetGenericTypeDefinition();
|
||||
if (genericDefinition == typeof(KeyValuePair<,>))
|
||||
{
|
||||
var args = itemType.GetGenericArguments();
|
||||
DictionaryType = typeof(RecyclableDictionary<,>).MakeGenericType(args);
|
||||
|
||||
var listType = typeof(RecyclableLongList<>).MakeGenericType(itemType);
|
||||
var method = typeof(zRecyclableLongListAddRange).GetMethod(
|
||||
nameof(AddRange),
|
||||
BindingFlags.NonPublic | BindingFlags.Static,
|
||||
null,
|
||||
new[] { listType, DictionaryType },
|
||||
null)!.MakeGenericMethod(args);
|
||||
|
||||
var listParam = Expression.Parameter(typeof(RecyclableLongList<T>), "list");
|
||||
var itemsParam = Expression.Parameter(typeof(IEnumerable<T>), "items");
|
||||
var call = Expression.Call(method,
|
||||
Expression.Convert(listParam, listType),
|
||||
Expression.Convert(itemsParam, DictionaryType));
|
||||
|
||||
DictionaryAdder = Expression.Lambda<Action<RecyclableLongList<T>, IEnumerable<T>>>(call, listParam, itemsParam).Compile();
|
||||
}
|
||||
else if (genericDefinition == typeof(ValueTuple<,>))
|
||||
{
|
||||
var args = itemType.GetGenericArguments();
|
||||
SortedListType = typeof(RecyclableSortedList<,>).MakeGenericType(args);
|
||||
|
||||
var listType = typeof(RecyclableLongList<>).MakeGenericType(itemType);
|
||||
var method = typeof(zRecyclableLongListAddRange).GetMethod(
|
||||
nameof(AddRange),
|
||||
BindingFlags.NonPublic | BindingFlags.Static,
|
||||
null,
|
||||
new[] { listType, SortedListType },
|
||||
null)!.MakeGenericMethod(args);
|
||||
|
||||
var listParam = Expression.Parameter(typeof(RecyclableLongList<T>), "list");
|
||||
var itemsParam = Expression.Parameter(typeof(IEnumerable<T>), "items");
|
||||
var call = Expression.Call(method,
|
||||
Expression.Convert(listParam, listType),
|
||||
Expression.Convert(itemsParam, SortedListType));
|
||||
|
||||
SortedListAdder = Expression.Lambda<Action<RecyclableLongList<T>, IEnumerable<T>>>(call, listParam, itemsParam).Compile();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddRangeEnumerated<T>(this RecyclableLongList<T> targetList, IEnumerable<T> items)
|
||||
{
|
||||
@@ -499,12 +439,8 @@ namespace Recyclable.Collections
|
||||
targetList.AddRange(sourceQueue);
|
||||
return;
|
||||
|
||||
case var _ when AddRangeHelper<T>.DictionaryAdder != null && AddRangeHelper<T>.DictionaryType!.IsInstanceOfType(items):
|
||||
AddRangeHelper<T>.DictionaryAdder!(targetList, items);
|
||||
return;
|
||||
|
||||
case var _ when AddRangeHelper<T>.SortedListAdder != null && AddRangeHelper<T>.SortedListType!.IsInstanceOfType(items):
|
||||
AddRangeHelper<T>.SortedListAdder!(targetList, items);
|
||||
case IAddRangeProvider<T> provider:
|
||||
provider.AddRangeTo(targetList);
|
||||
return;
|
||||
|
||||
default:
|
||||
|
||||
@@ -5,7 +5,7 @@ using Recyclable.Collections.Pools;
|
||||
|
||||
namespace Recyclable.Collections
|
||||
{
|
||||
internal sealed class RecyclableSortedList<TKey, TValue> : IEnumerable<(TKey Key, TValue Value)>, IDisposable
|
||||
internal sealed class RecyclableSortedList<TKey, TValue> : IEnumerable<(TKey Key, TValue Value)>, IDisposable, IAddRangeProvider<(TKey Key, TValue Value)>
|
||||
where TKey : notnull
|
||||
{
|
||||
internal static readonly bool _needsClearing = !typeof(TKey).IsValueType || !typeof(TValue).IsValueType;
|
||||
@@ -276,5 +276,15 @@ namespace Recyclable.Collections
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void IAddRangeProvider<(TKey Key, TValue Value)>.AddRangeTo(RecyclableList<(TKey Key, TValue Value)> list)
|
||||
{
|
||||
zRecyclableListAddRange.AddRange(list, this);
|
||||
}
|
||||
|
||||
void IAddRangeProvider<(TKey Key, TValue Value)>.AddRangeTo(RecyclableLongList<(TKey Key, TValue Value)> list)
|
||||
{
|
||||
zRecyclableLongListAddRange.AddRange(list, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user