Skip to content

Commit 05289ff

Browse files
committed
Performance: Allow caching of enum field information.
1 parent ea53ed2 commit 05289ff

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# vNext
22
- Added support for PhpProperty on enums, allowing consumers to specify different field names
3+
- Performance: Cache enum field information with `TypeCacheFlag.PropertyInfo`.
34

45
# 1.0.0
56

PhpSerializerNET/PhpDeserializer.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ internal class PhpDeserializer {
2222
private static readonly Dictionary<Type, Dictionary<string, PropertyInfo>> PropertyInfoCache = new();
2323

2424
private static Dictionary<Type, Dictionary<string, FieldInfo>> FieldInfoCache { get; set; } = new();
25+
private static Dictionary<Type, Dictionary<string, FieldInfo>> EnumInfoCache { get; set; } = new();
2526

2627
public PhpDeserializer(string input, PhpDeserializationOptions options) {
2728
_options = options;
@@ -58,6 +59,7 @@ public static void ClearTypeCache() {
5859
/// </summary>
5960
public static void ClearPropertyInfoCache() {
6061
PropertyInfoCache.Clear();
62+
EnumInfoCache.Clear();
6163
}
6264

6365
private object DeserializeToken(PhpSerializeToken token) {
@@ -254,16 +256,32 @@ private object DeserializeTokenFromSimpleType(Type givenType, PhpSerializeToken
254256
return Enum.Parse(targetType, token.Value);
255257
}
256258

257-
var foundFieldInfo = targetType
258-
.GetFields()
259-
.Select(fieldInfo => new { fieldInfo, phpPropertyAttribute = fieldInfo.GetCustomAttribute<PhpPropertyAttribute>() })
260-
.FirstOrDefault(c => c.fieldInfo.Name == token.Value || c.phpPropertyAttribute != null && c.phpPropertyAttribute.Name == token.Value)
261-
?.fieldInfo;
259+
260+
FieldInfo foundFieldInfo = null;
261+
if (this._options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo)) {
262+
if (!EnumInfoCache.ContainsKey(targetType)) {
263+
EnumInfoCache.Add(targetType, new());
264+
}
265+
if (EnumInfoCache[targetType].ContainsKey(token.Value)) {
266+
foundFieldInfo = EnumInfoCache[targetType][token.Value];
267+
}
268+
}
262269

263270
if (foundFieldInfo == null) {
264-
throw new DeserializationException(
265-
$"Exception encountered while trying to assign '{token.Value}' to type '{targetType.Name}'. " +
266-
$"The value could not be matched to an enum member.");
271+
foundFieldInfo = targetType
272+
.GetFields()
273+
.Select(fieldInfo => new { fieldInfo, phpPropertyAttribute = fieldInfo.GetCustomAttribute<PhpPropertyAttribute>() })
274+
.FirstOrDefault(c => c.fieldInfo.Name == token.Value || c.phpPropertyAttribute != null && c.phpPropertyAttribute.Name == token.Value)
275+
?.fieldInfo;
276+
if (this._options.TypeCache.HasFlag(TypeCacheFlag.PropertyInfo)) {
277+
EnumInfoCache[targetType].Add(token.Value, foundFieldInfo);
278+
}
279+
}
280+
281+
if (foundFieldInfo == null) {
282+
throw new DeserializationException(
283+
$"Exception encountered while trying to assign '{token.Value}' to type '{targetType.Name}'. " +
284+
$"The value could not be matched to an enum member.");
267285
}
268286

269287
return foundFieldInfo.GetRawConstantValue();

0 commit comments

Comments
 (0)