From 7532f0256f58e0d11711da4e159534bccbf266f0 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Fri, 12 Jun 2015 13:07:51 +0100 Subject: Reimplement RepeatedField using an array as the backing store. This is effectively reimplementing List, 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...) --- csharp/src/ProtocolBuffers/CodedInputStream.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'csharp/src/ProtocolBuffers/CodedInputStream.cs') diff --git a/csharp/src/ProtocolBuffers/CodedInputStream.cs b/csharp/src/ProtocolBuffers/CodedInputStream.cs index 17fcc64b..447adbb1 100644 --- a/csharp/src/ProtocolBuffers/CodedInputStream.cs +++ b/csharp/src/ProtocolBuffers/CodedInputStream.cs @@ -38,6 +38,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +using Google.Protobuf.Collections; using Google.Protobuf.Descriptors; namespace Google.Protobuf @@ -700,7 +701,7 @@ namespace Google.Protobuf } } - public void ReadEnumArray(uint fieldTag, ICollection list) + public void ReadEnumArray(uint fieldTag, RepeatedField list) where T : struct, IComparable, IFormattable { WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag); @@ -712,8 +713,8 @@ namespace Google.Protobuf int limit = PushLimit(length); while (!ReachedLimit) { - // TODO(jonskeet): Avoid this horrible boxing! - list.Add((T)(object) ReadEnum()); + // Ghastly hack, but it works... + list.AddInt32(ReadEnum()); } PopLimit(limit); } -- cgit v1.2.3