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] [Pure]
public static bool[] Unpack(this byte value) public static bool[] Unpack(this byte value)
{ {
Span<bool> buffer = stackalloc bool[Size]; bool[] buffer = new bool[Size];
value.Unpack(buffer); value.Unpack(buffer);
return buffer.ToArray(); return buffer;
} }
/// <summary> /// <summary>

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ public static class SpanExtensions
#else #else
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
#endif #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); return Contains((ReadOnlySpan<T>)span, value);
} }
@ -40,12 +40,15 @@ public static class SpanExtensions
#else #else
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
#endif #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 // Use MemoryMarshal.CreateSpan instead of using creating new Span instance from pointer will trim down a lot of instructions
// on Release mode. // on Release mode.
// https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABABgAJiBGAOgCUBXAOwwEt8YaBJFmKCAA4BlPgDdWYGLgDcAWABQZSrUYt2nAMIR8A1gBs+IqOMkyFxAExVzFIQAtsUAQBlsweszYc588wGZyGCYGfHIAFSkMAFFg0JByVhZyAG8FcnTyAEE0cgAhHI0cgBE0BQBfBX9KC3INFLSMgG0AKVYMAHEgvgkACgwATwEYCAAzHojcaNiASmmAXQb0xoBZGAw7CAATLh09HtX1rZ2BPQB5ATYIJlwaTIBzO9hcXFZRGB49RMS78kJyA4221250u11uDyeLzeIPYrAAXthQfNFpQAtQkORmLhsCMYORgBAIHp/mtAVQADxhAB8PSEAmwTEpVPIuHpTByYXIomwegYMGm5AA7nY+HjOfEYiF6vIMrLyLARgkkkEQrhyABeeUwRUAVWuOM4mVwlJyiQwNIVJPw0H6y0cuAcehonQwdG1oqYkh6rIZsx8coyxAA7FabXaoA6eTQNLBETA6QyepaVfhcDkfUwaM4gnd1tNo1cMNhErgenrsbjbsawqaWBbtVyeXy/SiKjKMiiWm1OkxumA+oNhmMJlMQrMFu2lgCjrt9qSZycYVcbvdHlIoe8mJ8mN9fiTDkDFxdWMvwWvnq8YDD8PDESemMjJ6jlBisQb8YTidPNhYmbS2UyLJshyja8vyQoirA4TkBKsTSgG6TBuQvaCuQCaMmaNLlgaVYAAoQGafBJg2qzWlAtr2o6zprG6uKwJ6MDemyszpmyWY5nmBYsMW1xlvqlZGiaSrmsRircmBLZPm2ZRAA=== // 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... // 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 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 #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] [Pure]
public static byte[] GetBytes(this double value) public static byte[] GetBytes(this double value)
{ {
Span<byte> buffer = stackalloc byte[8]; byte[] buffer = new byte[8];
value.TryWriteBytes(buffer); value.TryWriteBytes(buffer);
return buffer.ToArray(); return buffer;
} }
/// <summary> /// <summary>
@ -31,9 +31,9 @@ public static class DoubleExtensions
[Pure] [Pure]
public static byte[] GetBytes(this double value, Endianness endianness) public static byte[] GetBytes(this double value, Endianness endianness)
{ {
Span<byte> buffer = stackalloc byte[8]; byte[] buffer = new byte[8];
value.TryWriteBytes(buffer, endianness); value.TryWriteBytes(buffer, endianness);
return buffer.ToArray(); return buffer;
} }
/// <summary> /// <summary>

View File

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

View File

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

View File

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