Optimize DictionaryExtensions and handle CodeAnalysis errors

This commit is contained in:
RealityProgrammer 2023-03-06 07:50:10 +07:00
parent 4300e35b4e
commit a808cab37f
9 changed files with 74 additions and 37 deletions

View File

@ -22,9 +22,9 @@ public static class ByteExtensions
[Pure]
public static bool[] Unpack(this byte value)
{
Span<bool> buffer = stackalloc bool[Size];
bool[] buffer = new bool[Size];
value.Unpack(buffer);
return buffer.ToArray();
return buffer;
}
/// <summary>

View File

@ -69,7 +69,7 @@ public static class CollectionExtensions
continue;
}
await item.DisposeAsync();
await item.DisposeAsync().ConfigureAwait(false);
}
source.Clear();

View File

@ -58,7 +58,8 @@ public static class DictionaryExtensions
if (exists)
{
value = updateValueFactory(key, value!);
} else
}
else
{
value = addValue;
}
@ -67,11 +68,15 @@ public static class DictionaryExtensions
#else
if (dictionary.TryGetValue(key, out var old))
{
dictionary[key] = updateValueFactory(key, old);
var newValue = updateValueFactory(key, old);
dictionary[key] = newValue;
return newValue;
}
else
{
dictionary.Add(key, addValue);
return addValue;
}
#endif
}
@ -121,14 +126,16 @@ public static class DictionaryExtensions
if (dictionary.TryGetValue(key, out var old))
{
dictionary[key] = updateValueFactory(key, old);
var newValue = updateValueFactory(key, old);
dictionary[key] = newValue;
return newValue;
}
else
{
dictionary.Add(key, addValue);
return addValue;
}
return dictionary[key];
}
/// <summary>
@ -199,14 +206,18 @@ public static class DictionaryExtensions
#else
if (dictionary.TryGetValue(key, out var old))
{
dictionary[key] = updateValueFactory(key, old);
var update = updateValueFactory(key, old);
dictionary[key] = update;
return update;
}
else
{
dictionary.Add(key, addValueFactory(key));
}
var add = addValueFactory(key);
dictionary.Add(key, add);
return dictionary[key];
return add;
}
#endif
}
@ -265,14 +276,18 @@ public static class DictionaryExtensions
if (dictionary.TryGetValue(key, out var old))
{
dictionary[key] = updateValueFactory(key, old);
var update = updateValueFactory(key, old);
dictionary[key] = update;
return update;
}
else
{
dictionary.Add(key, addValueFactory(key));
}
var add = addValueFactory(key);
dictionary.Add(key, add);
return dictionary[key];
return add;
}
}
/// <summary>
@ -349,14 +364,18 @@ public static class DictionaryExtensions
#else
if (dictionary.TryGetValue(key, out var old))
{
dictionary[key] = updateValueFactory(key, old, factoryArgument);
var update = updateValueFactory(key, old, factoryArgument);
dictionary[key] = update;
return update;
}
else
{
dictionary.Add(key, addValueFactory(key, factoryArgument));
}
var add = addValueFactory(key, factoryArgument);
dictionary.Add(key, add);
return dictionary[key];
return add;
}
#endif
}
@ -421,14 +440,18 @@ public static class DictionaryExtensions
if (dictionary.TryGetValue(key, out var old))
{
dictionary[key] = updateValueFactory(key, old, factoryArgument);
var update = updateValueFactory(key, old, factoryArgument);
dictionary[key] = update;
return update;
}
else
{
dictionary.Add(key, addValueFactory(key, factoryArgument));
}
var add = addValueFactory(key, factoryArgument);
dictionary.Add(key, add);
return dictionary[key];
return add;
}
}
/// <summary>

View File

@ -124,7 +124,7 @@ public static class EnumerableExtensions
continue;
}
await item.DisposeAsync();
await item.DisposeAsync().ConfigureAwait(false);
}
}

View File

@ -22,7 +22,7 @@ public static class SpanExtensions
#else
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
#endif
public static bool Contains<T>(this Span<T> span, T value) where T : Enum
public static bool Contains<T>(this Span<T> span, T value) where T : struct, Enum
{
return Contains((ReadOnlySpan<T>)span, value);
}
@ -40,12 +40,15 @@ public static class SpanExtensions
#else
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
#endif
public static bool Contains<T>(this ReadOnlySpan<T> span, T value)
public static bool Contains<T>(this ReadOnlySpan<T> span, T value) where T : struct, Enum
{
#if NET6_0_OR_GREATER
// Use MemoryMarshal.CreateSpan instead of using creating new Span instance from pointer will trim down a lot of instructions
// on Release mode.
// https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABABgAJiBGAOgCUBXAOwwEt8YaBJFmKCAA4BlPgDdWYGLgDcAWABQZSrUYt2nAMIR8A1gBs+IqOMkyFxAExVzFIQAtsUAQBlsweszYc588wGZyGCYGfHIAFSkMAFFg0JByVhZyAG8FcnTyAEE0cgAhHI0cgBE0BQBfBX9KC3INFLSMgG0AKVYMAHEgvgkACgwATwEYCAAzHojcaNiASmmAXQb0xoBZGAw7CAATLh09HtX1rZ2BPQB5ATYIJlwaTIBzO9hcXFZRGB49RMS78kJyA4221250u11uDyeLzeIPYrAAXthQfNFpQAtQkORmLhsCMYORgBAIHp/mtAVQADxhAB8PSEAmwTEpVPIuHpTByYXIomwegYMGm5AA7nY+HjOfEYiF6vIMrLyLARgkkkEQrhyABeeUwRUAVWuOM4mVwlJyiQwNIVJPw0H6y0cuAcehonQwdG1oqYkh6rIZsx8coyxAA7FabXaoA6eTQNLBETA6QyepaVfhcDkfUwaM4gnd1tNo1cMNhErgenrsbjbsawqaWBbtVyeXy/SiKjKMiiWm1OkxumA+oNhmMJlMQrMFu2lgCjrt9qSZycYVcbvdHlIoe8mJ8mN9fiTDkDFxdWMvwWvnq8YDD8PDESemMjJ6jlBisQb8YTidPNhYmbS2UyLJshyja8vyQoirA4TkBKsTSgG6TBuQvaCuQCaMmaNLlgaVYAAoQGafBJg2qzWlAtr2o6zprG6uKwJ6MDemyszpmyWY5nmBYsMW1xlvqlZGiaSrmsRircmBLZPm2ZRAA===
// Also use reference instead of MemoryMarshal.Cast to remove boundary check (or something, it just result in something like that).
// TODO: Figure out some kind of way to directly pass the Span directly into Contains call, which make method smaller and more prone to inlining...
unsafe
{
@ -85,5 +88,16 @@ public static class SpanExtensions
}
#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
}
#else // NET6_0_OR_GREATER
foreach (var it in span)
{
if (EqualityComparer<T>.Default.Equals(it, value))
{
return true;
}
}
return false;
#endif // NET6_0_OR_GREATER
}
}

View File

@ -17,9 +17,9 @@ public static class DoubleExtensions
[Pure]
public static byte[] GetBytes(this double value)
{
Span<byte> buffer = stackalloc byte[8];
byte[] buffer = new byte[8];
value.TryWriteBytes(buffer);
return buffer.ToArray();
return buffer;
}
/// <summary>
@ -31,9 +31,9 @@ public static class DoubleExtensions
[Pure]
public static byte[] GetBytes(this double value, Endianness endianness)
{
Span<byte> buffer = stackalloc byte[8];
byte[] buffer = new byte[8];
value.TryWriteBytes(buffer, endianness);
return buffer.ToArray();
return buffer;
}
/// <summary>

View File

@ -16,9 +16,9 @@ public static class Int16Extensions
[Pure]
public static byte[] GetBytes(this short value)
{
Span<byte> buffer = stackalloc byte[2];
byte[] buffer = new byte[2];
value.TryWriteBytes(buffer);
return buffer.ToArray();
return buffer;
}
/// <summary>
@ -30,9 +30,9 @@ public static class Int16Extensions
[Pure]
public static byte[] GetBytes(this short value, Endianness endianness)
{
Span<byte> buffer = stackalloc byte[2];
byte[] buffer = new byte[2];
value.TryWriteBytes(buffer, endianness);
return buffer.ToArray();
return buffer;
}
/// <summary>

View File

@ -30,7 +30,7 @@ public static class Int32Extensions
[Pure]
public static byte[] GetBytes(this int value, Endianness endianness)
{
Span<byte> buffer = stackalloc byte[4];
byte[] buffer = new byte[4];
value.TryWriteBytes(buffer, endianness);
return buffer.ToArray();
}

View File

@ -133,7 +133,7 @@ public static class ComparableExtensions
if (lower.GreaterThan(upper))
{
throw new ArgumentException(
string.Format(ExceptionMessages.LowerCannotBeGreaterThanUpper, lower, upper),
string.Format(null, ExceptionMessages.LowerCannotBeGreaterThanUpper, lower, upper),
nameof(lower));
}