Skip to content

Commit 475bc10

Browse files
committed
Improve deserialization speed, again
1 parent 183e7af commit 475bc10

8 files changed

Lines changed: 75 additions & 64 deletions

File tree

src/AssetStudio.Extended.MonoBehaviours/AssetStudio.Extended.MonoBehaviours.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,15 @@
5555
<Compile Include="Serialization\Serialized\ObjectArray.cs" />
5656
<Compile Include="Serialization\Serialized\ObjectDictionary.cs" />
5757
<Compile Include="Serialization\Serialized\RawData.cs" />
58+
<Compile Include="Serialization\Serializers\Common\ConstructorManager.cs" />
59+
<Compile Include="Serialization\Serializers\Common\TypeConverterManager.cs" />
5860
<Compile Include="Serialization\Serializers\ISerializationContext.cs" />
5961
<Compile Include="Serialization\Serializers\ITypedSerializer.cs" />
6062
<Compile Include="Serialization\Serializers\SerializationContextCreator.cs" />
6163
<Compile Include="Serialization\Serializers\SerializationContextBase.cs" />
62-
<Compile Include="Serialization\Serializers\Dynamic\ConstructorManager.cs" />
6364
<Compile Include="Serialization\Serializers\Dynamic\MemberSetter.cs" />
6465
<Compile Include="Serialization\Serializers\Dynamic\DynamicSerializationContext.cs" />
6566
<Compile Include="Serialization\Serializers\Dynamic\TypedSerializerManager.cs" />
66-
<Compile Include="Serialization\Serializers\Dynamic\TypeConverterManager.cs" />
6767
<Compile Include="Serialization\Serializers\Dynamic\TypedSerializer.cs" />
6868
<Compile Include="Serialization\Serializers\Dynamic\TypedSerializer.Setters.cs" />
6969
<Compile Include="Serialization\Serializers\TypedSerializerBase.cs" />

src/AssetStudio.Extended.MonoBehaviours/Serialization/Serializers/Dynamic/ConstructorManager.cs renamed to src/AssetStudio.Extended.MonoBehaviours/Serialization/Serializers/Common/ConstructorManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Runtime.CompilerServices;
44
using JetBrains.Annotations;
55

6-
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Dynamic {
6+
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Common {
77
internal sealed class ConstructorManager {
88

99
public ConstructorManager() {

src/AssetStudio.Extended.MonoBehaviours/Serialization/Serializers/Dynamic/TypeConverterManager.cs renamed to src/AssetStudio.Extended.MonoBehaviours/Serialization/Serializers/Common/TypeConverterManager.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
using System;
22
using System.Collections.Generic;
33
using AssetStudio.Extended.MonoBehaviours.Extensions;
4+
using AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Dynamic;
45
using JetBrains.Annotations;
56

6-
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Dynamic {
7+
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Common {
78
internal sealed class TypeConverterManager {
89

9-
public TypeConverterManager([NotNull] DynamicSerializationContext context) {
10+
public TypeConverterManager([NotNull] ISerializationContext context) {
1011
Context = context;
1112
_createdTypeConverters = new Dictionary<Type, ISimpleTypeConverter>(10);
1213
}
1314

1415
[NotNull]
15-
public DynamicSerializationContext Context { get; }
16-
17-
public void RegisterConverter([NotNull] Type converterType) {
18-
if (!converterType.ImplementsInterface(typeof(ISimpleTypeConverter))) {
19-
throw new InvalidCastException("The converter does not implement " + nameof(ISimpleTypeConverter) + ".");
20-
}
21-
22-
var converter = Context.Activator.CreateInstance(converterType, true);
23-
24-
RegisterConverter((ISimpleTypeConverter)converter);
25-
}
16+
public ISerializationContext Context { get; }
2617

2718
public void RegisterConverter([NotNull] ISimpleTypeConverter converter) {
2819
var converterType = converter.GetType();
Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Common;
23
using JetBrains.Annotations;
34

45
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Dynamic {
@@ -13,26 +14,20 @@ public DynamicSerializationContext() {
1314
Serializers = new TypedSerializerManager(this);
1415
}
1516

16-
[NotNull]
17-
public ConstructorManager Activator { get; }
17+
public override ConstructorManager Activator { get; }
1818

19-
[NotNull]
20-
public TypeConverterManager Converters { get; }
19+
public override TypeConverterManager Converters { get; }
2120

2221
[NotNull]
2322
public TypedSerializerManager Serializers { get; }
2423

25-
public override ITypedSerializer GetSerializerOf(Type type) {
26-
return Serializers.GetSerializerOf(type);
24+
public override ITypedSerializer GetSerializerOf(Type containerType) {
25+
return Serializers.GetSerializerOf(containerType);
2726
}
2827

2928
public override void RegisterConverter(ISimpleTypeConverter converter) {
3029
Converters.RegisterConverter(converter);
3130
}
3231

33-
public override void RegisterConverter(Type converterType) {
34-
Converters.RegisterConverter(converterType);
35-
}
36-
3732
}
3833
}

src/AssetStudio.Extended.MonoBehaviours/Serialization/Serializers/Dynamic/TypedSerializer.Setters.cs

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Reflection;
5+
using System.Runtime.CompilerServices;
56
using AssetStudio.Extended.MonoBehaviours.Serialization.Naming;
67
using JetBrains.Annotations;
78

89
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Dynamic {
910
partial class TypedSerializer {
1011

1112
[NotNull]
12-
private MemberSetter FindSetterByName([NotNull] string name, [CanBeNull] INamingConvention naming) {
13+
private MemberSetter FindSetterByName([NotNull] string serializedName, [CanBeNull] INamingConvention naming) {
14+
if (_createdSetters.ContainsKey(serializedName)) {
15+
return _createdSetters[serializedName];
16+
}
17+
1318
var properties = _properties;
1419

1520
Debug.Assert(properties != null, nameof(properties) + " != null");
@@ -18,57 +23,50 @@ private MemberSetter FindSetterByName([NotNull] string name, [CanBeNull] INaming
1823

1924
Debug.Assert(fields != null, nameof(fields) + " != null");
2025

21-
MemberSetter result;
26+
MemberSetter result = null;
27+
ScriptableObjectPropertyAttribute sopa;
2228

2329
foreach (var prop in properties) {
24-
ScriptableObjectPropertyAttribute sopa;
25-
2630
if (_propertyAttributeCache.ContainsKey(prop)) {
2731
sopa = _propertyAttributeCache[prop];
2832
} else {
2933
sopa = prop.GetCustomAttribute<ScriptableObjectPropertyAttribute>();
3034
_propertyAttributeCache[prop] = sopa;
3135
}
3236

33-
var propName = !string.IsNullOrEmpty(sopa?.Name) ? sopa.Name : (naming != null ? naming.GetCorrected(prop.Name) : prop.Name);
34-
35-
if (propName == name) {
36-
if (_createdSetters.ContainsKey(propName)) {
37-
result = _createdSetters[propName];
38-
} else {
39-
result = new MemberSetter(prop, sopa);
40-
_createdSetters[propName] = result;
41-
}
37+
var propName = GetCorrectedMemberName(sopa, naming, prop.Name);
4238

43-
return result;
39+
if (string.Equals(propName, serializedName, StringComparison.Ordinal)) {
40+
result = new MemberSetter(prop, sopa);
41+
break;
4442
}
4543
}
4644

47-
foreach (var field in fields) {
48-
ScriptableObjectPropertyAttribute sopa;
49-
50-
if (_fieldAttributeCache.ContainsKey(field)) {
51-
sopa = _fieldAttributeCache[field];
52-
} else {
53-
sopa = field.GetCustomAttribute<ScriptableObjectPropertyAttribute>();
54-
_fieldAttributeCache[field] = sopa;
55-
}
45+
if (result == null) {
46+
foreach (var field in fields) {
47+
if (_fieldAttributeCache.ContainsKey(field)) {
48+
sopa = _fieldAttributeCache[field];
49+
} else {
50+
sopa = field.GetCustomAttribute<ScriptableObjectPropertyAttribute>();
51+
_fieldAttributeCache[field] = sopa;
52+
}
5653

57-
var fieldName = !string.IsNullOrEmpty(sopa?.Name) ? sopa.Name : (naming != null ? naming.GetCorrected(field.Name) : field.Name);
54+
var fieldName = GetCorrectedMemberName(sopa, naming, field.Name);
5855

59-
if (fieldName == name) {
60-
if (_createdSetters.ContainsKey(fieldName)) {
61-
result = _createdSetters[fieldName];
62-
} else {
56+
if (string.Equals(fieldName, serializedName, StringComparison.Ordinal)) {
6357
result = new MemberSetter(field, sopa);
64-
_createdSetters[fieldName] = result;
58+
break;
6559
}
66-
67-
return result;
6860
}
6961
}
7062

71-
return MemberSetter.Null;
63+
if (result == null) {
64+
result = MemberSetter.Null;
65+
}
66+
67+
_createdSetters[serializedName] = result;
68+
69+
return result;
7270
}
7371

7472
private void SetValue([NotNull] MemberSetter setter, [CanBeNull] object obj, [CanBeNull] object value, [NotNull] Type serializedValueType) {
@@ -101,6 +99,12 @@ private void SetValue([NotNull] MemberSetter setter, [CanBeNull] object obj, [Ca
10199
setter.SetValueDirect(obj, convertedValue);
102100
}
103101

102+
[NotNull]
103+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
104+
private static string GetCorrectedMemberName([CanBeNull] ScriptableObjectPropertyAttribute sopa, [CanBeNull] INamingConvention naming, [NotNull] string fallback) {
105+
return !string.IsNullOrEmpty(sopa?.Name) ? sopa.Name : (naming != null ? naming.GetCorrected(fallback) : fallback);
106+
}
107+
104108
[NotNull]
105109
private readonly Dictionary<string, MemberSetter> _createdSetters;
106110

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
using System;
2+
using AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Common;
23
using JetBrains.Annotations;
34

45
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers {
5-
public interface ISerializationContext {
6+
internal interface ISerializationContext {
67

78
void RegisterConverter([NotNull] ISimpleTypeConverter converter);
89

910
void RegisterConverter([NotNull] Type converterType);
1011

1112
[NotNull]
12-
ITypedSerializer GetSerializerOf([NotNull] Type type);
13+
ITypedSerializer GetSerializerOf([NotNull] Type containerType);
14+
15+
[NotNull]
16+
ConstructorManager Activator { get; }
17+
18+
[NotNull]
19+
TypeConverterManager Converters { get; }
1320

1421
}
1522
}

src/AssetStudio.Extended.MonoBehaviours/Serialization/Serializers/ITypedSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using JetBrains.Annotations;
33

44
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers {
5-
public interface ITypedSerializer {
5+
internal interface ITypedSerializer {
66

77
/// <summary>
88
/// Deserialize a typed complex object.
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
using System;
2+
using AssetStudio.Extended.MonoBehaviours.Extensions;
3+
using AssetStudio.Extended.MonoBehaviours.Serialization.Serializers.Common;
24

35
namespace AssetStudio.Extended.MonoBehaviours.Serialization.Serializers {
4-
public abstract class SerializationContextBase : ISerializationContext {
6+
internal abstract class SerializationContextBase : ISerializationContext {
57

68
public abstract void RegisterConverter(ISimpleTypeConverter converter);
79

8-
public abstract void RegisterConverter(Type converterType);
10+
public virtual void RegisterConverter(Type converterType) {
11+
if (!converterType.ImplementsInterface(typeof(ISimpleTypeConverter))) {
12+
throw new InvalidCastException("The converter does not implement " + nameof(ISimpleTypeConverter) + ".");
13+
}
14+
15+
var converter = Activator.CreateInstance(converterType, true);
16+
17+
RegisterConverter((ISimpleTypeConverter)converter);
18+
}
919

1020
public void RegisterConverter<T>()
1121
where T : ISimpleTypeConverter {
1222
RegisterConverter(typeof(T));
1323
}
1424

15-
public abstract ITypedSerializer GetSerializerOf(Type type);
25+
public abstract ITypedSerializer GetSerializerOf(Type containerType);
26+
27+
public abstract ConstructorManager Activator { get; }
28+
29+
public abstract TypeConverterManager Converters { get; }
1630

1731
}
1832
}

0 commit comments

Comments
 (0)