Skip to content

Commit 6640a04

Browse files
committed
Introduce EnumCache to reduce performance impact of reflection
1 parent 810ae77 commit 6640a04

File tree

4 files changed

+20
-6
lines changed

4 files changed

+20
-6
lines changed

Source/Common/ByteReader.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Text;
3+
using Multiplayer.Common.Util;
34

45
namespace Multiplayer.Common
56
{
@@ -139,7 +140,7 @@ public virtual ulong[] ReadPrefixedULongs()
139140

140141
public virtual T ReadEnum<T>() where T : Enum
141142
{
142-
var values = Enum.GetValues(typeof(T));
143+
var values = EnumCache.GetValues(typeof(T));
143144
ushort enumIndex = values.Length switch
144145
{
145146
<= byte.MaxValue => ReadByte(),

Source/Common/ByteWriter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Runtime.CompilerServices;
66
using System.Text;
7+
using Multiplayer.Common.Util;
78

89
namespace Multiplayer.Common
910
{
@@ -85,7 +86,7 @@ public virtual ByteWriter WriteString(string? s)
8586

8687
public virtual void WriteEnum<T>(T value) where T : Enum
8788
{
88-
var values = Enum.GetValues(value.GetType());
89+
var values = EnumCache.GetValues(value.GetType());
8990
var index = Array.IndexOf(values, value);
9091
switch (values.Length)
9192
{

Source/Common/ScheduledCommand.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
32

43
namespace Multiplayer.Common
54
{
@@ -32,7 +31,8 @@ public ScheduledCommand(CommandType type, int ticks, int factionId, int mapId, i
3231
public static byte[] Serialize(ScheduledCommand cmd)
3332
{
3433
ByteWriter writer = new ByteWriter();
35-
writer.WriteEnum(cmd.type);
34+
// Use WriteByte directly instead of WriteEnum for better performance, as this is frequently used.
35+
writer.WriteByte((byte)cmd.type);
3636
writer.WriteInt32(cmd.ticks);
3737
writer.WriteInt32(cmd.factionId);
3838
writer.WriteInt32(cmd.mapId);
@@ -44,7 +44,8 @@ public static byte[] Serialize(ScheduledCommand cmd)
4444

4545
public static ScheduledCommand Deserialize(ByteReader data)
4646
{
47-
CommandType cmd = data.ReadEnum<CommandType>();
47+
// Use ReadByte directly instead of ReadEnum for better performance, as this is frequently used.
48+
CommandType cmd = (CommandType)data.ReadByte();
4849
int ticks = data.ReadInt32();
4950
int factionId = data.ReadInt32();
5051
int mapId = data.ReadInt32();

Source/Common/Util/EnumCache.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
4+
namespace Multiplayer.Common.Util;
5+
6+
internal static class EnumCache
7+
{
8+
private static readonly ConcurrentDictionary<Type, Array> Cache = new();
9+
10+
public static Array GetValues(Type enumType) => Cache.GetOrAdd(enumType, Enum.GetValues);
11+
}

0 commit comments

Comments
 (0)