Skip to content

Commit eb05557

Browse files
author
rstam
committed
CSHARP-750: Added optimizations for ThreeDimensionalArraySerializer and TwoDimensionalArraySerializer.
1 parent 060902a commit eb05557

File tree

2 files changed

+124
-12
lines changed

2 files changed

+124
-12
lines changed

MongoDB.Bson/Serialization/Serializers/ThreeDimensionalArraySerializer.cs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,18 @@ public override object Deserialize(
6363
bsonReader.ReadNull();
6464
return null;
6565
case BsonType.Array:
66+
var itemNominalType = typeof(T);
67+
var itemNominalTypeIsValueType = itemNominalType.IsValueType;
68+
var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType);
69+
var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType);
70+
Type lastItemType = null;
71+
IBsonSerializer lastItemSerializer = null;
72+
73+
// if itemNominalType is a value type then these assignments are final
74+
var itemActualType = itemNominalType;
75+
var itemActualTypeSerializer = itemNominalTypeSerializer;
76+
6677
bsonReader.ReadStartArray();
67-
var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(T));
6878
var outerList = new List<List<List<T>>>();
6979
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
7080
{
@@ -76,10 +86,26 @@ public override object Deserialize(
7686
var innerList = new List<T>();
7787
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
7888
{
79-
var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
80-
var serializer = BsonSerializer.LookupSerializer(elementType);
81-
var element = (T)serializer.Deserialize(bsonReader, typeof(T), elementType, itemSerializationOptions);
82-
innerList.Add(element);
89+
if (!itemNominalTypeIsValueType)
90+
{
91+
itemActualType = itemDiscriminatorConvention.GetActualType(bsonReader, itemNominalType);
92+
if (itemActualType == itemNominalType)
93+
{
94+
itemActualTypeSerializer = itemNominalTypeSerializer;
95+
}
96+
else if (itemActualType == lastItemType)
97+
{
98+
itemActualTypeSerializer = lastItemSerializer;
99+
}
100+
else
101+
{
102+
itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType);
103+
lastItemType = itemActualType;
104+
lastItemSerializer = itemActualTypeSerializer;
105+
}
106+
}
107+
var item = (T)itemActualTypeSerializer.Deserialize(bsonReader, itemNominalType, itemActualType, itemSerializationOptions);
108+
innerList.Add(item);
83109
}
84110
bsonReader.ReadEndArray();
85111
middleList.Add(innerList);
@@ -166,6 +192,17 @@ public override void Serialize(
166192
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
167193
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
168194

195+
var itemNominalType = typeof(T);
196+
var itemNominalTypeIsValueType = itemNominalType.IsValueType;
197+
var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType);
198+
var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType);
199+
Type lastItemType = null;
200+
IBsonSerializer lastItemSerializer = null;
201+
202+
// if itemNominalType is a value type then these assignments are final
203+
var itemActualType = itemNominalType;
204+
var itemActualTypeSerializer = itemNominalTypeSerializer;
205+
169206
bsonWriter.WriteStartArray();
170207
var length1 = array.GetLength(0);
171208
var length2 = array.GetLength(1);
@@ -178,7 +215,26 @@ public override void Serialize(
178215
bsonWriter.WriteStartArray();
179216
for (int k = 0; k < length3; k++)
180217
{
181-
BsonSerializer.Serialize(bsonWriter, typeof(T), array[i, j, k], itemSerializationOptions);
218+
var item = array[i, j, k];
219+
if (!itemNominalTypeIsValueType)
220+
{
221+
itemActualType = item == null ? itemNominalType : item.GetType();
222+
if (itemActualType == itemNominalType)
223+
{
224+
itemActualTypeSerializer = itemNominalTypeSerializer;
225+
}
226+
else if (itemActualType == lastItemType)
227+
{
228+
itemActualTypeSerializer = lastItemSerializer;
229+
}
230+
else
231+
{
232+
itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType);
233+
lastItemType = itemActualType;
234+
lastItemSerializer = itemActualTypeSerializer;
235+
}
236+
}
237+
itemActualTypeSerializer.Serialize(bsonWriter, itemNominalType, item, itemSerializationOptions);
182238
}
183239
bsonWriter.WriteEndArray();
184240
}

MongoDB.Bson/Serialization/Serializers/TwoDimensionalArraySerializer.cs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,45 @@ public override object Deserialize(
6363
bsonReader.ReadNull();
6464
return null;
6565
case BsonType.Array:
66+
var itemNominalType = typeof(T);
67+
var itemNominalTypeIsValueType = itemNominalType.IsValueType;
68+
var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType);
69+
var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType);
70+
Type lastItemType = null;
71+
IBsonSerializer lastItemSerializer = null;
72+
73+
// if itemNominalType is a value type then these assignments are final
74+
var itemActualType = itemNominalType;
75+
var itemActualTypeSerializer = itemNominalTypeSerializer;
76+
6677
bsonReader.ReadStartArray();
67-
var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(T));
6878
var outerList = new List<List<T>>();
6979
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
7080
{
7181
bsonReader.ReadStartArray();
7282
var innerList = new List<T>();
7383
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
7484
{
75-
var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
76-
var serializer = BsonSerializer.LookupSerializer(elementType);
77-
var element = (T)serializer.Deserialize(bsonReader, typeof(T), elementType, itemSerializationOptions);
78-
innerList.Add(element);
85+
if (!itemNominalTypeIsValueType)
86+
{
87+
itemActualType = itemDiscriminatorConvention.GetActualType(bsonReader, itemNominalType);
88+
if (itemActualType == itemNominalType)
89+
{
90+
itemActualTypeSerializer = itemNominalTypeSerializer;
91+
}
92+
else if (itemActualType == lastItemType)
93+
{
94+
itemActualTypeSerializer = lastItemSerializer;
95+
}
96+
else
97+
{
98+
itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType);
99+
lastItemType = itemActualType;
100+
lastItemSerializer = itemActualTypeSerializer;
101+
}
102+
}
103+
var item = (T)itemActualTypeSerializer.Deserialize(bsonReader, itemNominalType, itemActualType, itemSerializationOptions);
104+
innerList.Add(item);
79105
}
80106
bsonReader.ReadEndArray();
81107
outerList.Add(innerList);
@@ -149,6 +175,17 @@ public override void Serialize(
149175
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
150176
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
151177

178+
var itemNominalType = typeof(T);
179+
var itemNominalTypeIsValueType = itemNominalType.IsValueType;
180+
var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType);
181+
var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType);
182+
Type lastItemType = null;
183+
IBsonSerializer lastItemSerializer = null;
184+
185+
// if itemNominalType is a value type then these assignments are final
186+
var itemActualType = itemNominalType;
187+
var itemActualTypeSerializer = itemNominalTypeSerializer;
188+
152189
bsonWriter.WriteStartArray();
153190
var length1 = array.GetLength(0);
154191
var length2 = array.GetLength(1);
@@ -157,7 +194,26 @@ public override void Serialize(
157194
bsonWriter.WriteStartArray();
158195
for (int j = 0; j < length2; j++)
159196
{
160-
BsonSerializer.Serialize(bsonWriter, typeof(T), array[i, j], itemSerializationOptions);
197+
var item = array[i, j];
198+
if (!itemNominalTypeIsValueType)
199+
{
200+
itemActualType = item == null ? itemNominalType : item.GetType();
201+
if (itemActualType == itemNominalType)
202+
{
203+
itemActualTypeSerializer = itemNominalTypeSerializer;
204+
}
205+
else if (itemActualType == lastItemType)
206+
{
207+
itemActualTypeSerializer = lastItemSerializer;
208+
}
209+
else
210+
{
211+
itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType);
212+
lastItemType = itemActualType;
213+
lastItemSerializer = itemActualTypeSerializer;
214+
}
215+
}
216+
itemActualTypeSerializer.Serialize(bsonWriter, itemNominalType, item, itemSerializationOptions);
161217
}
162218
bsonWriter.WriteEndArray();
163219
}

0 commit comments

Comments
 (0)