xref: /aosp_15_r20/external/protobuf/csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker #region Copyright notice and license
2*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format
3*1b3f573fSAndroid Build Coastguard Worker // Copyright 2019 Google Inc.  All rights reserved.
4*1b3f573fSAndroid Build Coastguard Worker // https://github.com/protocolbuffers/protobuf
5*1b3f573fSAndroid Build Coastguard Worker //
6*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without
7*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are
8*1b3f573fSAndroid Build Coastguard Worker // met:
9*1b3f573fSAndroid Build Coastguard Worker //
10*1b3f573fSAndroid Build Coastguard Worker //     * Redistributions of source code must retain the above copyright
11*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer.
12*1b3f573fSAndroid Build Coastguard Worker //     * Redistributions in binary form must reproduce the above
13*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer
14*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the
15*1b3f573fSAndroid Build Coastguard Worker // distribution.
16*1b3f573fSAndroid Build Coastguard Worker //     * Neither the name of Google Inc. nor the names of its
17*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from
18*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission.
19*1b3f573fSAndroid Build Coastguard Worker //
20*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*1b3f573fSAndroid Build Coastguard Worker #endregion
32*1b3f573fSAndroid Build Coastguard Worker 
33*1b3f573fSAndroid Build Coastguard Worker using BenchmarkDotNet.Attributes;
34*1b3f573fSAndroid Build Coastguard Worker using System;
35*1b3f573fSAndroid Build Coastguard Worker using System.Collections.Generic;
36*1b3f573fSAndroid Build Coastguard Worker using System.IO;
37*1b3f573fSAndroid Build Coastguard Worker using System.Linq;
38*1b3f573fSAndroid Build Coastguard Worker using System.Buffers;
39*1b3f573fSAndroid Build Coastguard Worker using Google.Protobuf.WellKnownTypes;
40*1b3f573fSAndroid Build Coastguard Worker using Benchmarks.Proto3;
41*1b3f573fSAndroid Build Coastguard Worker 
42*1b3f573fSAndroid Build Coastguard Worker namespace Google.Protobuf.Benchmarks
43*1b3f573fSAndroid Build Coastguard Worker {
44*1b3f573fSAndroid Build Coastguard Worker     /// <summary>
45*1b3f573fSAndroid Build Coastguard Worker     /// Benchmark that tests parsing performance for various messages.
46*1b3f573fSAndroid Build Coastguard Worker     /// </summary>
47*1b3f573fSAndroid Build Coastguard Worker     [MemoryDiagnoser]
48*1b3f573fSAndroid Build Coastguard Worker     public class ParseMessagesBenchmark
49*1b3f573fSAndroid Build Coastguard Worker     {
50*1b3f573fSAndroid Build Coastguard Worker         const int MaxMessages = 100;
51*1b3f573fSAndroid Build Coastguard Worker 
52*1b3f573fSAndroid Build Coastguard Worker         SubTest manyWrapperFieldsTest = new SubTest(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages);
53*1b3f573fSAndroid Build Coastguard Worker         SubTest manyPrimitiveFieldsTest = new SubTest(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages);
54*1b3f573fSAndroid Build Coastguard Worker         SubTest repeatedFieldTest = new SubTest(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages);
55*1b3f573fSAndroid Build Coastguard Worker         SubTest emptyMessageTest = new SubTest(new Empty(), Empty.Parser, () => new Empty(), MaxMessages);
56*1b3f573fSAndroid Build Coastguard Worker 
57*1b3f573fSAndroid Build Coastguard Worker         public IEnumerable<int> MessageCountValues => new[] { 10, 100 };
58*1b3f573fSAndroid Build Coastguard Worker 
59*1b3f573fSAndroid Build Coastguard Worker         [GlobalSetup]
GlobalSetup()60*1b3f573fSAndroid Build Coastguard Worker         public void GlobalSetup()
61*1b3f573fSAndroid Build Coastguard Worker         {
62*1b3f573fSAndroid Build Coastguard Worker         }
63*1b3f573fSAndroid Build Coastguard Worker 
64*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
ManyWrapperFieldsMessage_ParseFromByteArray()65*1b3f573fSAndroid Build Coastguard Worker         public IMessage ManyWrapperFieldsMessage_ParseFromByteArray()
66*1b3f573fSAndroid Build Coastguard Worker         {
67*1b3f573fSAndroid Build Coastguard Worker             return manyWrapperFieldsTest.ParseFromByteArray();
68*1b3f573fSAndroid Build Coastguard Worker         }
69*1b3f573fSAndroid Build Coastguard Worker 
70*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
ManyWrapperFieldsMessage_ParseFromReadOnlySequence()71*1b3f573fSAndroid Build Coastguard Worker         public IMessage ManyWrapperFieldsMessage_ParseFromReadOnlySequence()
72*1b3f573fSAndroid Build Coastguard Worker         {
73*1b3f573fSAndroid Build Coastguard Worker             return manyWrapperFieldsTest.ParseFromReadOnlySequence();
74*1b3f573fSAndroid Build Coastguard Worker         }
75*1b3f573fSAndroid Build Coastguard Worker 
76*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
ManyPrimitiveFieldsMessage_ParseFromByteArray()77*1b3f573fSAndroid Build Coastguard Worker         public IMessage ManyPrimitiveFieldsMessage_ParseFromByteArray()
78*1b3f573fSAndroid Build Coastguard Worker         {
79*1b3f573fSAndroid Build Coastguard Worker             return manyPrimitiveFieldsTest.ParseFromByteArray();
80*1b3f573fSAndroid Build Coastguard Worker         }
81*1b3f573fSAndroid Build Coastguard Worker 
82*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
ManyPrimitiveFieldsMessage_ParseFromReadOnlySequence()83*1b3f573fSAndroid Build Coastguard Worker         public IMessage ManyPrimitiveFieldsMessage_ParseFromReadOnlySequence()
84*1b3f573fSAndroid Build Coastguard Worker         {
85*1b3f573fSAndroid Build Coastguard Worker             return manyPrimitiveFieldsTest.ParseFromReadOnlySequence();
86*1b3f573fSAndroid Build Coastguard Worker         }
87*1b3f573fSAndroid Build Coastguard Worker 
88*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
RepeatedFieldMessage_ParseFromByteArray()89*1b3f573fSAndroid Build Coastguard Worker         public IMessage RepeatedFieldMessage_ParseFromByteArray()
90*1b3f573fSAndroid Build Coastguard Worker         {
91*1b3f573fSAndroid Build Coastguard Worker             return repeatedFieldTest.ParseFromByteArray();
92*1b3f573fSAndroid Build Coastguard Worker         }
93*1b3f573fSAndroid Build Coastguard Worker 
94*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
RepeatedFieldMessage_ParseFromReadOnlySequence()95*1b3f573fSAndroid Build Coastguard Worker         public IMessage RepeatedFieldMessage_ParseFromReadOnlySequence()
96*1b3f573fSAndroid Build Coastguard Worker         {
97*1b3f573fSAndroid Build Coastguard Worker             return repeatedFieldTest.ParseFromReadOnlySequence();
98*1b3f573fSAndroid Build Coastguard Worker         }
99*1b3f573fSAndroid Build Coastguard Worker 
100*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
EmptyMessage_ParseFromByteArray()101*1b3f573fSAndroid Build Coastguard Worker         public IMessage EmptyMessage_ParseFromByteArray()
102*1b3f573fSAndroid Build Coastguard Worker         {
103*1b3f573fSAndroid Build Coastguard Worker             return emptyMessageTest.ParseFromByteArray();
104*1b3f573fSAndroid Build Coastguard Worker         }
105*1b3f573fSAndroid Build Coastguard Worker 
106*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
EmptyMessage_ParseFromReadOnlySequence()107*1b3f573fSAndroid Build Coastguard Worker         public IMessage EmptyMessage_ParseFromReadOnlySequence()
108*1b3f573fSAndroid Build Coastguard Worker         {
109*1b3f573fSAndroid Build Coastguard Worker             return emptyMessageTest.ParseFromReadOnlySequence();
110*1b3f573fSAndroid Build Coastguard Worker         }
111*1b3f573fSAndroid Build Coastguard Worker 
112*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
113*1b3f573fSAndroid Build Coastguard Worker         [ArgumentsSource(nameof(MessageCountValues))]
ManyWrapperFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)114*1b3f573fSAndroid Build Coastguard Worker         public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
115*1b3f573fSAndroid Build Coastguard Worker         {
116*1b3f573fSAndroid Build Coastguard Worker             manyWrapperFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount);
117*1b3f573fSAndroid Build Coastguard Worker         }
118*1b3f573fSAndroid Build Coastguard Worker 
119*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
120*1b3f573fSAndroid Build Coastguard Worker         [ArgumentsSource(nameof(MessageCountValues))]
ManyWrapperFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)121*1b3f573fSAndroid Build Coastguard Worker         public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
122*1b3f573fSAndroid Build Coastguard Worker         {
123*1b3f573fSAndroid Build Coastguard Worker             manyWrapperFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
124*1b3f573fSAndroid Build Coastguard Worker         }
125*1b3f573fSAndroid Build Coastguard Worker 
126*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
127*1b3f573fSAndroid Build Coastguard Worker         [ArgumentsSource(nameof(MessageCountValues))]
ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)128*1b3f573fSAndroid Build Coastguard Worker         public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
129*1b3f573fSAndroid Build Coastguard Worker         {
130*1b3f573fSAndroid Build Coastguard Worker             manyPrimitiveFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount);
131*1b3f573fSAndroid Build Coastguard Worker         }
132*1b3f573fSAndroid Build Coastguard Worker 
133*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
134*1b3f573fSAndroid Build Coastguard Worker         [ArgumentsSource(nameof(MessageCountValues))]
ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)135*1b3f573fSAndroid Build Coastguard Worker         public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
136*1b3f573fSAndroid Build Coastguard Worker         {
137*1b3f573fSAndroid Build Coastguard Worker             manyPrimitiveFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
138*1b3f573fSAndroid Build Coastguard Worker         }
139*1b3f573fSAndroid Build Coastguard Worker 
140*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
141*1b3f573fSAndroid Build Coastguard Worker         [ArgumentsSource(nameof(MessageCountValues))]
RepeatedFieldMessage_ParseDelimitedMessagesFromByteArray(int messageCount)142*1b3f573fSAndroid Build Coastguard Worker         public void RepeatedFieldMessage_ParseDelimitedMessagesFromByteArray(int messageCount)
143*1b3f573fSAndroid Build Coastguard Worker         {
144*1b3f573fSAndroid Build Coastguard Worker             repeatedFieldTest.ParseDelimitedMessagesFromByteArray(messageCount);
145*1b3f573fSAndroid Build Coastguard Worker         }
146*1b3f573fSAndroid Build Coastguard Worker 
147*1b3f573fSAndroid Build Coastguard Worker         [Benchmark]
148*1b3f573fSAndroid Build Coastguard Worker         [ArgumentsSource(nameof(MessageCountValues))]
RepeatedFieldMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)149*1b3f573fSAndroid Build Coastguard Worker         public void RepeatedFieldMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
150*1b3f573fSAndroid Build Coastguard Worker         {
151*1b3f573fSAndroid Build Coastguard Worker             repeatedFieldTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount);
152*1b3f573fSAndroid Build Coastguard Worker         }
153*1b3f573fSAndroid Build Coastguard Worker 
CreateManyWrapperFieldsMessage()154*1b3f573fSAndroid Build Coastguard Worker         public static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage()
155*1b3f573fSAndroid Build Coastguard Worker         {
156*1b3f573fSAndroid Build Coastguard Worker             // Example data match data of an internal benchmarks
157*1b3f573fSAndroid Build Coastguard Worker             return new ManyWrapperFieldsMessage()
158*1b3f573fSAndroid Build Coastguard Worker             {
159*1b3f573fSAndroid Build Coastguard Worker                 Int64Field19 = 123,
160*1b3f573fSAndroid Build Coastguard Worker                 Int64Field37 = 1000032,
161*1b3f573fSAndroid Build Coastguard Worker                 Int64Field26 = 3453524500,
162*1b3f573fSAndroid Build Coastguard Worker                 DoubleField79 = 1.2,
163*1b3f573fSAndroid Build Coastguard Worker                 DoubleField25 = 234,
164*1b3f573fSAndroid Build Coastguard Worker                 DoubleField9 = 123.3,
165*1b3f573fSAndroid Build Coastguard Worker                 DoubleField28 = 23,
166*1b3f573fSAndroid Build Coastguard Worker                 DoubleField7 = 234,
167*1b3f573fSAndroid Build Coastguard Worker                 DoubleField50 = 2.45
168*1b3f573fSAndroid Build Coastguard Worker             };
169*1b3f573fSAndroid Build Coastguard Worker         }
170*1b3f573fSAndroid Build Coastguard Worker 
CreateManyPrimitiveFieldsMessage()171*1b3f573fSAndroid Build Coastguard Worker         public static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage()
172*1b3f573fSAndroid Build Coastguard Worker         {
173*1b3f573fSAndroid Build Coastguard Worker             // Example data match data of an internal benchmarks
174*1b3f573fSAndroid Build Coastguard Worker             return new ManyPrimitiveFieldsMessage()
175*1b3f573fSAndroid Build Coastguard Worker             {
176*1b3f573fSAndroid Build Coastguard Worker                 Int64Field19 = 123,
177*1b3f573fSAndroid Build Coastguard Worker                 Int64Field37 = 1000032,
178*1b3f573fSAndroid Build Coastguard Worker                 Int64Field26 = 3453524500,
179*1b3f573fSAndroid Build Coastguard Worker                 DoubleField79 = 1.2,
180*1b3f573fSAndroid Build Coastguard Worker                 DoubleField25 = 234,
181*1b3f573fSAndroid Build Coastguard Worker                 DoubleField9 = 123.3,
182*1b3f573fSAndroid Build Coastguard Worker                 DoubleField28 = 23,
183*1b3f573fSAndroid Build Coastguard Worker                 DoubleField7 = 234,
184*1b3f573fSAndroid Build Coastguard Worker                 DoubleField50 = 2.45
185*1b3f573fSAndroid Build Coastguard Worker             };
186*1b3f573fSAndroid Build Coastguard Worker         }
187*1b3f573fSAndroid Build Coastguard Worker 
CreateRepeatedFieldMessage()188*1b3f573fSAndroid Build Coastguard Worker         public static GoogleMessage1 CreateRepeatedFieldMessage()
189*1b3f573fSAndroid Build Coastguard Worker         {
190*1b3f573fSAndroid Build Coastguard Worker             // Message with a repeated fixed length item collection
191*1b3f573fSAndroid Build Coastguard Worker             var message = new GoogleMessage1();
192*1b3f573fSAndroid Build Coastguard Worker             for (ulong i = 0; i < 1000; i++)
193*1b3f573fSAndroid Build Coastguard Worker             {
194*1b3f573fSAndroid Build Coastguard Worker                 message.Field5.Add(i);
195*1b3f573fSAndroid Build Coastguard Worker             }
196*1b3f573fSAndroid Build Coastguard Worker             return message;
197*1b3f573fSAndroid Build Coastguard Worker         }
198*1b3f573fSAndroid Build Coastguard Worker 
199*1b3f573fSAndroid Build Coastguard Worker         private class SubTest
200*1b3f573fSAndroid Build Coastguard Worker         {
201*1b3f573fSAndroid Build Coastguard Worker             private readonly IMessage message;
202*1b3f573fSAndroid Build Coastguard Worker             private readonly MessageParser parser;
203*1b3f573fSAndroid Build Coastguard Worker             private readonly Func<IMessage> factory;
204*1b3f573fSAndroid Build Coastguard Worker             private readonly byte[] data;
205*1b3f573fSAndroid Build Coastguard Worker             private readonly byte[] multipleMessagesData;
206*1b3f573fSAndroid Build Coastguard Worker 
207*1b3f573fSAndroid Build Coastguard Worker             private ReadOnlySequence<byte> dataSequence;
208*1b3f573fSAndroid Build Coastguard Worker             private ReadOnlySequence<byte> multipleMessagesDataSequence;
209*1b3f573fSAndroid Build Coastguard Worker 
SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount)210*1b3f573fSAndroid Build Coastguard Worker             public SubTest(IMessage message, MessageParser parser, Func<IMessage> factory, int maxMessageCount)
211*1b3f573fSAndroid Build Coastguard Worker             {
212*1b3f573fSAndroid Build Coastguard Worker                 this.message = message;
213*1b3f573fSAndroid Build Coastguard Worker                 this.parser = parser;
214*1b3f573fSAndroid Build Coastguard Worker                 this.factory = factory;
215*1b3f573fSAndroid Build Coastguard Worker                 this.data = message.ToByteArray();
216*1b3f573fSAndroid Build Coastguard Worker                 this.multipleMessagesData = CreateBufferWithMultipleMessages(message, maxMessageCount);
217*1b3f573fSAndroid Build Coastguard Worker                 this.dataSequence = new ReadOnlySequence<byte>(this.data);
218*1b3f573fSAndroid Build Coastguard Worker                 this.multipleMessagesDataSequence = new ReadOnlySequence<byte>(this.multipleMessagesData);
219*1b3f573fSAndroid Build Coastguard Worker             }
220*1b3f573fSAndroid Build Coastguard Worker 
ParseFromByteArray()221*1b3f573fSAndroid Build Coastguard Worker             public IMessage ParseFromByteArray() => parser.ParseFrom(data);
222*1b3f573fSAndroid Build Coastguard Worker 
ParseFromReadOnlySequence()223*1b3f573fSAndroid Build Coastguard Worker             public IMessage ParseFromReadOnlySequence() => parser.ParseFrom(dataSequence);
224*1b3f573fSAndroid Build Coastguard Worker 
ParseDelimitedMessagesFromByteArray(int messageCount)225*1b3f573fSAndroid Build Coastguard Worker             public void ParseDelimitedMessagesFromByteArray(int messageCount)
226*1b3f573fSAndroid Build Coastguard Worker             {
227*1b3f573fSAndroid Build Coastguard Worker                 var input = new CodedInputStream(multipleMessagesData);
228*1b3f573fSAndroid Build Coastguard Worker                 for (int i = 0; i < messageCount; i++)
229*1b3f573fSAndroid Build Coastguard Worker                 {
230*1b3f573fSAndroid Build Coastguard Worker                     var msg = factory();
231*1b3f573fSAndroid Build Coastguard Worker                     input.ReadMessage(msg);
232*1b3f573fSAndroid Build Coastguard Worker                 }
233*1b3f573fSAndroid Build Coastguard Worker             }
234*1b3f573fSAndroid Build Coastguard Worker 
ParseDelimitedMessagesFromReadOnlySequence(int messageCount)235*1b3f573fSAndroid Build Coastguard Worker             public void ParseDelimitedMessagesFromReadOnlySequence(int messageCount)
236*1b3f573fSAndroid Build Coastguard Worker             {
237*1b3f573fSAndroid Build Coastguard Worker                 ParseContext.Initialize(multipleMessagesDataSequence, out ParseContext ctx);
238*1b3f573fSAndroid Build Coastguard Worker                 for (int i = 0; i < messageCount; i++)
239*1b3f573fSAndroid Build Coastguard Worker                 {
240*1b3f573fSAndroid Build Coastguard Worker                     var msg = factory();
241*1b3f573fSAndroid Build Coastguard Worker                     ctx.ReadMessage(msg);
242*1b3f573fSAndroid Build Coastguard Worker                 }
243*1b3f573fSAndroid Build Coastguard Worker             }
244*1b3f573fSAndroid Build Coastguard Worker 
CreateBufferWithMultipleMessages(IMessage msg, int msgCount)245*1b3f573fSAndroid Build Coastguard Worker             private static byte[] CreateBufferWithMultipleMessages(IMessage msg, int msgCount)
246*1b3f573fSAndroid Build Coastguard Worker             {
247*1b3f573fSAndroid Build Coastguard Worker                 var ms = new MemoryStream();
248*1b3f573fSAndroid Build Coastguard Worker                 var cos = new CodedOutputStream(ms);
249*1b3f573fSAndroid Build Coastguard Worker                 for (int i = 0; i < msgCount; i++)
250*1b3f573fSAndroid Build Coastguard Worker                 {
251*1b3f573fSAndroid Build Coastguard Worker                     cos.WriteMessage(msg);
252*1b3f573fSAndroid Build Coastguard Worker                 }
253*1b3f573fSAndroid Build Coastguard Worker                 cos.Flush();
254*1b3f573fSAndroid Build Coastguard Worker                 return ms.ToArray();
255*1b3f573fSAndroid Build Coastguard Worker             }
256*1b3f573fSAndroid Build Coastguard Worker         }
257*1b3f573fSAndroid Build Coastguard Worker     }
258*1b3f573fSAndroid Build Coastguard Worker }
259