Skip to content

Commit b1002f7

Browse files
Avoid reflection when validating enums (#2676)
1 parent 99d1328 commit b1002f7

File tree

1 file changed

+17
-1
lines changed
  • crates/bindings-csharp/BSATN.Runtime/BSATN

1 file changed

+17
-1
lines changed

crates/bindings-csharp/BSATN.Runtime/BSATN/Runtime.cs

+17-1
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,25 @@ public interface IReadWrite<T>
5050
public readonly struct Enum<T> : IReadWrite<T>
5151
where T : struct, Enum
5252
{
53+
private static readonly ulong NumVariants;
54+
55+
static Enum()
56+
{
57+
NumVariants = (ulong)Enum.GetValues(typeof(T)).Length;
58+
}
59+
5360
private static T Validate(T value)
5461
{
55-
if (!Enum.IsDefined(typeof(T), value))
62+
// Previously this was: `if (!Enum.IsDefined(typeof(T), value))`.
63+
// This was quite expensive because:
64+
// 1. It uses reflection
65+
// 2. It allocates
66+
// 3. It is called on each row when decoding
67+
//
68+
// However, enum values are guaranteed to be sequential and zero based.
69+
// Hence we only ever need to do an upper bound check.
70+
// See `SpacetimeDB.Type.ParseEnum` for the syntax analysis.
71+
if (Convert.ToUInt64(value) >= NumVariants)
5672
{
5773
throw new ArgumentOutOfRangeException(
5874
nameof(value),

0 commit comments

Comments
 (0)