aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/ProtocolBuffers/CodedOutputStream.cs
diff options
context:
space:
mode:
authorJon Skeet <skeet@pobox.com>2015-06-12 13:07:51 +0100
committerJon Skeet <skeet@pobox.com>2015-06-12 13:07:51 +0100
commit7532f0256f58e0d11711da4e159534bccbf266f0 (patch)
tree246de5832a971caff8dcf85db1f971aed2c48f3c /csharp/src/ProtocolBuffers/CodedOutputStream.cs
parent5a33827eec75b980fb152c531e4c6b75ce5af015 (diff)
downloadprotobuf-7532f0256f58e0d11711da4e159534bccbf266f0.tar.gz
protobuf-7532f0256f58e0d11711da4e159534bccbf266f0.tar.bz2
protobuf-7532f0256f58e0d11711da4e159534bccbf266f0.zip
Reimplement RepeatedField<T> using an array as the backing store.
This is effectively reimplementing List<T>, but with a few advantages: - We know that an empty repeated field is common, so don't allocate an array until we need to - With direct access to the array, we can easily convert enum values to int without boxing - We can relax the restrictions over what happens if the repeated field is modified while iterating, avoiding so much checking This is somewhat risky, in that reimplementing a building block like this is *always* risky, but hey... (The performance benefits are significant...)
Diffstat (limited to 'csharp/src/ProtocolBuffers/CodedOutputStream.cs')
-rw-r--r--csharp/src/ProtocolBuffers/CodedOutputStream.cs23
1 files changed, 14 insertions, 9 deletions
diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.cs
index dfcaf8a2..bc3ed7d7 100644
--- a/csharp/src/ProtocolBuffers/CodedOutputStream.cs
+++ b/csharp/src/ProtocolBuffers/CodedOutputStream.cs
@@ -743,10 +743,11 @@ namespace Google.Protobuf
{
return;
}
- // TODO(jonskeet): Avoid the Cast call here. Work out a better mass "T to int" conversion.
- foreach (int value in list.Cast<int>())
+ // Bit of a hack, to access the values as ints
+ var iterator = list.GetInt32Enumerator();
+ while (iterator.MoveNext())
{
- WriteEnum(fieldNumber, value);
+ WriteEnum(fieldNumber, iterator.Current);
}
}
@@ -956,15 +957,19 @@ namespace Google.Protobuf
{
return;
}
- // Obviously, we'll want to get rid of this hack...
- var temporaryHack = new RepeatedField<int>();
- temporaryHack.Add(list.Cast<int>());
- uint size = temporaryHack.CalculateSize(ComputeEnumSizeNoTag);
+ // Bit of a hack, to access the values as ints
+ var iterator = list.GetInt32Enumerator();
+ uint size = 0;
+ while (iterator.MoveNext())
+ {
+ size += (uint) ComputeEnumSizeNoTag(iterator.Current);
+ }
+ iterator.Reset();
WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
WriteRawVarint32(size);
- foreach (int value in temporaryHack)
+ while (iterator.MoveNext())
{
- WriteEnumNoTag(value);
+ WriteEnumNoTag(iterator.Current);
}
}