• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Protocol Buffers - Google's data interchange format
2// Copyright 2013 Google Inc.  All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
8#import "GPBTestUtilities.h"
9#import "objectivec/Tests/Unittest.pbobjc.h"
10#import "objectivec/Tests/UnittestImport.pbobjc.h"
11#import "objectivec/Tests/UnittestObjc.pbobjc.h"
12
13//
14// This file really just uses the unittests framework as a testbed to
15// run some simple performance tests. The data can then be used to help
16// evaluate changes to the runtime.
17//
18
19static const uint32_t kRepeatedCount = 100;
20
21@interface PerfTests : GPBTestCase
22@end
23
24@implementation PerfTests
25
26- (void)setUp {
27  // A convenient place to put a break point if you want to connect instruments.
28  [super setUp];
29}
30
31- (void)testMessagePerformance {
32  [self measureBlock:^{
33    for (int i = 0; i < 200; ++i) {
34      TestAllTypes* message = [[TestAllTypes alloc] init];
35      [self setAllFields:message repeatedCount:kRepeatedCount];
36      NSData* rawBytes = [message data];
37      [message release];
38      message = [[TestAllTypes alloc] initWithData:rawBytes error:NULL];
39      [message release];
40    }
41  }];
42}
43
44- (void)testMessageSerialParsingPerformance {
45  // This and the next test are meant to monitor that the parsing functionality of protos does not
46  // lock across threads when parsing different instances. The Serial version of the test should run
47  // around ~2 times slower than the Parallel version since it's parsing the protos in the same
48  // thread.
49  TestAllTypes* allTypesMessage = [TestAllTypes message];
50  [self setAllFields:allTypesMessage repeatedCount:2];
51  NSData* allTypesData = allTypesMessage.data;
52
53  [self measureBlock:^{
54    for (int i = 0; i < 500; ++i) {
55      [TestAllTypes parseFromData:allTypesData error:NULL];
56      [TestAllTypes parseFromData:allTypesData error:NULL];
57    }
58  }];
59}
60
61- (void)testMessageParallelParsingPerformance {
62  // This and the previous test are meant to monitor that the parsing functionality of protos does
63  // not lock across threads when parsing different instances. The Serial version of the test should
64  // run around ~2 times slower than the Parallel version since it's parsing the protos in the same
65  // thread.
66  TestAllTypes* allTypesMessage = [TestAllTypes message];
67  [self setAllFields:allTypesMessage repeatedCount:2];
68  NSData* allTypesData = allTypesMessage.data;
69
70  dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
71
72  [self measureBlock:^{
73    for (int i = 0; i < 500; ++i) {
74      dispatch_group_t group = dispatch_group_create();
75
76      dispatch_group_async(group, concurrentQueue, ^{
77        [TestAllTypes parseFromData:allTypesData error:NULL];
78      });
79
80      dispatch_group_async(group, concurrentQueue, ^{
81        [TestAllTypes parseFromData:allTypesData error:NULL];
82      });
83
84      dispatch_group_notify(group, concurrentQueue,
85                            ^{
86                            });
87
88      dispatch_release(group);
89    }
90  }];
91
92  dispatch_release(concurrentQueue);
93}
94
95- (void)testMessageSerialExtensionsParsingPerformance {
96  // This and the next test are meant to monitor that the parsing functionality of protos does not
97  // lock across threads when parsing different instances when using extensions. The Serial version
98  // of the test should run around ~2 times slower than the Parallel version since it's parsing the
99  // protos in the same thread.
100  TestAllExtensions* allExtensionsMessage = [TestAllExtensions message];
101  [self setAllExtensions:allExtensionsMessage repeatedCount:2];
102  NSData* allExtensionsData = allExtensionsMessage.data;
103
104  [self measureBlock:^{
105    for (int i = 0; i < 500; ++i) {
106      [TestAllExtensions parseFromData:allExtensionsData
107                     extensionRegistry:[self extensionRegistry]
108                                 error:NULL];
109      [TestAllExtensions parseFromData:allExtensionsData
110                     extensionRegistry:[self extensionRegistry]
111                                 error:NULL];
112    }
113  }];
114}
115
116- (void)testMessageParallelExtensionsParsingPerformance {
117  // This and the previous test are meant to monitor that the parsing functionality of protos does
118  // not lock across threads when parsing different instances when using extensions. The Serial
119  // version of the test should run around ~2 times slower than the Parallel version since it's
120  // parsing the protos in the same thread.
121  TestAllExtensions* allExtensionsMessage = [TestAllExtensions message];
122  [self setAllExtensions:allExtensionsMessage repeatedCount:2];
123  NSData* allExtensionsData = allExtensionsMessage.data;
124
125  dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
126
127  [self measureBlock:^{
128    for (int i = 0; i < 500; ++i) {
129      dispatch_group_t group = dispatch_group_create();
130
131      dispatch_group_async(group, concurrentQueue, ^{
132        [TestAllExtensions parseFromData:allExtensionsData
133                       extensionRegistry:[UnittestRoot extensionRegistry]
134                                   error:NULL];
135      });
136
137      dispatch_group_async(group, concurrentQueue, ^{
138        [TestAllExtensions parseFromData:allExtensionsData
139                       extensionRegistry:[UnittestRoot extensionRegistry]
140                                   error:NULL];
141      });
142
143      dispatch_group_notify(group, concurrentQueue,
144                            ^{
145                            });
146
147      dispatch_release(group);
148    }
149  }];
150
151  dispatch_release(concurrentQueue);
152}
153
154- (void)testExtensionsPerformance {
155  [self measureBlock:^{
156    for (int i = 0; i < 200; ++i) {
157      TestAllExtensions* message = [[TestAllExtensions alloc] init];
158      [self setAllExtensions:message repeatedCount:kRepeatedCount];
159      NSData* rawBytes = [message data];
160      [message release];
161      TestAllExtensions* message2 = [[TestAllExtensions alloc] initWithData:rawBytes error:NULL];
162      [message2 release];
163    }
164  }];
165}
166
167- (void)testPackedTypesPerformance {
168  [self measureBlock:^{
169    for (int i = 0; i < 1000; ++i) {
170      TestPackedTypes* message = [[TestPackedTypes alloc] init];
171      [self setPackedFields:message repeatedCount:kRepeatedCount];
172      NSData* rawBytes = [message data];
173      [message release];
174      message = [[TestPackedTypes alloc] initWithData:rawBytes error:NULL];
175      [message release];
176    }
177  }];
178}
179
180- (void)testPackedExtensionsPerformance {
181  [self measureBlock:^{
182    for (int i = 0; i < 1000; ++i) {
183      TestPackedExtensions* message = [[TestPackedExtensions alloc] init];
184      [self setPackedExtensions:message repeatedCount:kRepeatedCount];
185      NSData* rawBytes = [message data];
186      [message release];
187      TestPackedExtensions* message2 = [[TestPackedExtensions alloc] initWithData:rawBytes
188                                                                            error:NULL];
189      [message2 release];
190    }
191  }];
192}
193
194- (void)testHas {
195  TestAllTypes* message = [self allSetRepeatedCount:1];
196  [self measureBlock:^{
197    for (int i = 0; i < 10000; ++i) {
198      [message hasOptionalInt32];
199      message.hasOptionalInt32 = NO;
200      [message hasOptionalInt32];
201
202      [message hasOptionalInt64];
203      message.hasOptionalInt64 = NO;
204      [message hasOptionalInt64];
205
206      [message hasOptionalUint32];
207      message.hasOptionalUint32 = NO;
208      [message hasOptionalUint32];
209
210      [message hasOptionalUint64];
211      message.hasOptionalUint64 = NO;
212      [message hasOptionalUint64];
213
214      [message hasOptionalSint32];
215      message.hasOptionalSint32 = NO;
216      [message hasOptionalSint32];
217
218      [message hasOptionalSint64];
219      message.hasOptionalSint64 = NO;
220      [message hasOptionalSint64];
221
222      [message hasOptionalFixed32];
223      message.hasOptionalFixed32 = NO;
224      [message hasOptionalFixed32];
225
226      [message hasOptionalFixed64];
227      message.hasOptionalFixed64 = NO;
228      [message hasOptionalFixed64];
229
230      [message hasOptionalSfixed32];
231      message.hasOptionalSfixed32 = NO;
232      [message hasOptionalSfixed32];
233
234      [message hasOptionalSfixed64];
235      message.hasOptionalSfixed64 = NO;
236      [message hasOptionalSfixed64];
237
238      [message hasOptionalFloat];
239      message.hasOptionalFloat = NO;
240      [message hasOptionalFloat];
241
242      [message hasOptionalDouble];
243      message.hasOptionalDouble = NO;
244      [message hasOptionalDouble];
245
246      [message hasOptionalBool];
247      message.hasOptionalBool = NO;
248      [message hasOptionalBool];
249
250      [message hasOptionalString];
251      message.hasOptionalString = NO;
252      [message hasOptionalString];
253
254      [message hasOptionalBytes];
255      message.hasOptionalBytes = NO;
256      [message hasOptionalBytes];
257
258      [message hasOptionalGroup];
259      message.hasOptionalGroup = NO;
260      [message hasOptionalGroup];
261
262      [message hasOptionalNestedMessage];
263      message.hasOptionalNestedMessage = NO;
264      [message hasOptionalNestedMessage];
265
266      [message hasOptionalForeignMessage];
267      message.hasOptionalForeignMessage = NO;
268      [message hasOptionalForeignMessage];
269
270      [message hasOptionalImportMessage];
271      message.hasOptionalImportMessage = NO;
272      [message hasOptionalImportMessage];
273
274      [message.optionalGroup hasA];
275      message.optionalGroup.hasA = NO;
276      [message.optionalGroup hasA];
277
278      [message.optionalNestedMessage hasBb];
279      message.optionalNestedMessage.hasBb = NO;
280      [message.optionalNestedMessage hasBb];
281
282      [message.optionalForeignMessage hasC];
283      message.optionalForeignMessage.hasC = NO;
284      [message.optionalForeignMessage hasC];
285
286      [message.optionalImportMessage hasD];
287      message.optionalImportMessage.hasD = NO;
288      [message.optionalImportMessage hasD];
289
290      [message hasOptionalNestedEnum];
291      message.hasOptionalNestedEnum = NO;
292      [message hasOptionalNestedEnum];
293
294      [message hasOptionalForeignEnum];
295      message.hasOptionalForeignEnum = NO;
296      [message hasOptionalForeignEnum];
297
298      [message hasOptionalImportEnum];
299      message.hasOptionalImportEnum = NO;
300      [message hasOptionalImportEnum];
301
302      [message hasOptionalStringPiece];
303      message.hasOptionalStringPiece = NO;
304      [message hasOptionalStringPiece];
305
306      [message hasOptionalCord];
307      message.hasOptionalCord = NO;
308      [message hasOptionalCord];
309
310      [message hasDefaultInt32];
311      message.hasDefaultInt32 = NO;
312      [message hasDefaultInt32];
313
314      [message hasDefaultInt64];
315      message.hasDefaultInt64 = NO;
316      [message hasDefaultInt64];
317
318      [message hasDefaultUint32];
319      message.hasDefaultUint32 = NO;
320      [message hasDefaultUint32];
321
322      [message hasDefaultUint64];
323      message.hasDefaultUint64 = NO;
324      [message hasDefaultUint64];
325
326      [message hasDefaultSint32];
327      message.hasDefaultSint32 = NO;
328      [message hasDefaultSint32];
329
330      [message hasDefaultSint64];
331      message.hasDefaultSint64 = NO;
332      [message hasDefaultSint64];
333
334      [message hasDefaultFixed32];
335      message.hasDefaultFixed32 = NO;
336      [message hasDefaultFixed32];
337
338      [message hasDefaultFixed64];
339      message.hasDefaultFixed64 = NO;
340      [message hasDefaultFixed64];
341
342      [message hasDefaultSfixed32];
343      message.hasDefaultSfixed32 = NO;
344      [message hasDefaultSfixed32];
345
346      [message hasDefaultSfixed64];
347      message.hasDefaultSfixed64 = NO;
348      [message hasDefaultSfixed64];
349
350      [message hasDefaultFloat];
351      message.hasDefaultFloat = NO;
352      [message hasDefaultFloat];
353
354      [message hasDefaultDouble];
355      message.hasDefaultDouble = NO;
356      [message hasDefaultDouble];
357
358      [message hasDefaultBool];
359      message.hasDefaultBool = NO;
360      [message hasDefaultBool];
361
362      [message hasDefaultString];
363      message.hasDefaultString = NO;
364      [message hasDefaultString];
365
366      [message hasDefaultBytes];
367      message.hasDefaultBytes = NO;
368      [message hasDefaultBytes];
369
370      [message hasDefaultNestedEnum];
371      message.hasDefaultNestedEnum = NO;
372      [message hasDefaultNestedEnum];
373
374      [message hasDefaultForeignEnum];
375      message.hasDefaultForeignEnum = NO;
376      [message hasDefaultForeignEnum];
377
378      [message hasDefaultImportEnum];
379      message.hasDefaultImportEnum = NO;
380      [message hasDefaultImportEnum];
381
382      [message hasDefaultStringPiece];
383      message.hasDefaultStringPiece = NO;
384      [message hasDefaultStringPiece];
385
386      [message hasDefaultCord];
387      message.hasDefaultCord = NO;
388      [message hasDefaultCord];
389    }
390  }];
391}
392
393@end
394