1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2013 Google Inc. All rights reserved.
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
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"
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.
19 static const uint32_t kRepeatedCount = 100;
21 @interface PerfTests : GPBTestCase
24 @implementation PerfTests
27 // A convenient place to put a break point if you want to connect instruments.
31 - (void)testMessagePerformance {
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];
38 message = [[TestAllTypes alloc] initWithData:rawBytes error:NULL];
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
49 TestAllTypes* allTypesMessage = [TestAllTypes message];
50 [self setAllFields:allTypesMessage repeatedCount:2];
51 NSData* allTypesData = allTypesMessage.data;
54 for (int i = 0; i < 500; ++i) {
55 [TestAllTypes parseFromData:allTypesData error:NULL];
56 [TestAllTypes parseFromData:allTypesData error:NULL];
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
66 TestAllTypes* allTypesMessage = [TestAllTypes message];
67 [self setAllFields:allTypesMessage repeatedCount:2];
68 NSData* allTypesData = allTypesMessage.data;
70 dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
73 for (int i = 0; i < 500; ++i) {
74 dispatch_group_t group = dispatch_group_create();
76 dispatch_group_async(group, concurrentQueue, ^{
77 [TestAllTypes parseFromData:allTypesData error:NULL];
80 dispatch_group_async(group, concurrentQueue, ^{
81 [TestAllTypes parseFromData:allTypesData error:NULL];
84 dispatch_group_notify(group, concurrentQueue,
88 dispatch_release(group);
92 dispatch_release(concurrentQueue);
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;
104 [self measureBlock:^{
105 for (int i = 0; i < 500; ++i) {
106 [TestAllExtensions parseFromData:allExtensionsData
107 extensionRegistry:[self extensionRegistry]
109 [TestAllExtensions parseFromData:allExtensionsData
110 extensionRegistry:[self extensionRegistry]
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;
125 dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
127 [self measureBlock:^{
128 for (int i = 0; i < 500; ++i) {
129 dispatch_group_t group = dispatch_group_create();
131 dispatch_group_async(group, concurrentQueue, ^{
132 [TestAllExtensions parseFromData:allExtensionsData
133 extensionRegistry:[UnittestRoot extensionRegistry]
137 dispatch_group_async(group, concurrentQueue, ^{
138 [TestAllExtensions parseFromData:allExtensionsData
139 extensionRegistry:[UnittestRoot extensionRegistry]
143 dispatch_group_notify(group, concurrentQueue,
147 dispatch_release(group);
151 dispatch_release(concurrentQueue);
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];
161 TestAllExtensions* message2 = [[TestAllExtensions alloc] initWithData:rawBytes error:NULL];
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];
174 message = [[TestPackedTypes alloc] initWithData:rawBytes error:NULL];
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];
187 TestPackedExtensions* message2 = [[TestPackedExtensions alloc] initWithData:rawBytes
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];
202 [message hasOptionalInt64];
203 message.hasOptionalInt64 = NO;
204 [message hasOptionalInt64];
206 [message hasOptionalUint32];
207 message.hasOptionalUint32 = NO;
208 [message hasOptionalUint32];
210 [message hasOptionalUint64];
211 message.hasOptionalUint64 = NO;
212 [message hasOptionalUint64];
214 [message hasOptionalSint32];
215 message.hasOptionalSint32 = NO;
216 [message hasOptionalSint32];
218 [message hasOptionalSint64];
219 message.hasOptionalSint64 = NO;
220 [message hasOptionalSint64];
222 [message hasOptionalFixed32];
223 message.hasOptionalFixed32 = NO;
224 [message hasOptionalFixed32];
226 [message hasOptionalFixed64];
227 message.hasOptionalFixed64 = NO;
228 [message hasOptionalFixed64];
230 [message hasOptionalSfixed32];
231 message.hasOptionalSfixed32 = NO;
232 [message hasOptionalSfixed32];
234 [message hasOptionalSfixed64];
235 message.hasOptionalSfixed64 = NO;
236 [message hasOptionalSfixed64];
238 [message hasOptionalFloat];
239 message.hasOptionalFloat = NO;
240 [message hasOptionalFloat];
242 [message hasOptionalDouble];
243 message.hasOptionalDouble = NO;
244 [message hasOptionalDouble];
246 [message hasOptionalBool];
247 message.hasOptionalBool = NO;
248 [message hasOptionalBool];
250 [message hasOptionalString];
251 message.hasOptionalString = NO;
252 [message hasOptionalString];
254 [message hasOptionalBytes];
255 message.hasOptionalBytes = NO;
256 [message hasOptionalBytes];
258 [message hasOptionalGroup];
259 message.hasOptionalGroup = NO;
260 [message hasOptionalGroup];
262 [message hasOptionalNestedMessage];
263 message.hasOptionalNestedMessage = NO;
264 [message hasOptionalNestedMessage];
266 [message hasOptionalForeignMessage];
267 message.hasOptionalForeignMessage = NO;
268 [message hasOptionalForeignMessage];
270 [message hasOptionalImportMessage];
271 message.hasOptionalImportMessage = NO;
272 [message hasOptionalImportMessage];
274 [message.optionalGroup hasA];
275 message.optionalGroup.hasA = NO;
276 [message.optionalGroup hasA];
278 [message.optionalNestedMessage hasBb];
279 message.optionalNestedMessage.hasBb = NO;
280 [message.optionalNestedMessage hasBb];
282 [message.optionalForeignMessage hasC];
283 message.optionalForeignMessage.hasC = NO;
284 [message.optionalForeignMessage hasC];
286 [message.optionalImportMessage hasD];
287 message.optionalImportMessage.hasD = NO;
288 [message.optionalImportMessage hasD];
290 [message hasOptionalNestedEnum];
291 message.hasOptionalNestedEnum = NO;
292 [message hasOptionalNestedEnum];
294 [message hasOptionalForeignEnum];
295 message.hasOptionalForeignEnum = NO;
296 [message hasOptionalForeignEnum];
298 [message hasOptionalImportEnum];
299 message.hasOptionalImportEnum = NO;
300 [message hasOptionalImportEnum];
302 [message hasOptionalStringPiece];
303 message.hasOptionalStringPiece = NO;
304 [message hasOptionalStringPiece];
306 [message hasOptionalCord];
307 message.hasOptionalCord = NO;
308 [message hasOptionalCord];
310 [message hasDefaultInt32];
311 message.hasDefaultInt32 = NO;
312 [message hasDefaultInt32];
314 [message hasDefaultInt64];
315 message.hasDefaultInt64 = NO;
316 [message hasDefaultInt64];
318 [message hasDefaultUint32];
319 message.hasDefaultUint32 = NO;
320 [message hasDefaultUint32];
322 [message hasDefaultUint64];
323 message.hasDefaultUint64 = NO;
324 [message hasDefaultUint64];
326 [message hasDefaultSint32];
327 message.hasDefaultSint32 = NO;
328 [message hasDefaultSint32];
330 [message hasDefaultSint64];
331 message.hasDefaultSint64 = NO;
332 [message hasDefaultSint64];
334 [message hasDefaultFixed32];
335 message.hasDefaultFixed32 = NO;
336 [message hasDefaultFixed32];
338 [message hasDefaultFixed64];
339 message.hasDefaultFixed64 = NO;
340 [message hasDefaultFixed64];
342 [message hasDefaultSfixed32];
343 message.hasDefaultSfixed32 = NO;
344 [message hasDefaultSfixed32];
346 [message hasDefaultSfixed64];
347 message.hasDefaultSfixed64 = NO;
348 [message hasDefaultSfixed64];
350 [message hasDefaultFloat];
351 message.hasDefaultFloat = NO;
352 [message hasDefaultFloat];
354 [message hasDefaultDouble];
355 message.hasDefaultDouble = NO;
356 [message hasDefaultDouble];
358 [message hasDefaultBool];
359 message.hasDefaultBool = NO;
360 [message hasDefaultBool];
362 [message hasDefaultString];
363 message.hasDefaultString = NO;
364 [message hasDefaultString];
366 [message hasDefaultBytes];
367 message.hasDefaultBytes = NO;
368 [message hasDefaultBytes];
370 [message hasDefaultNestedEnum];
371 message.hasDefaultNestedEnum = NO;
372 [message hasDefaultNestedEnum];
374 [message hasDefaultForeignEnum];
375 message.hasDefaultForeignEnum = NO;
376 [message hasDefaultForeignEnum];
378 [message hasDefaultImportEnum];
379 message.hasDefaultImportEnum = NO;
380 [message hasDefaultImportEnum];
382 [message hasDefaultStringPiece];
383 message.hasDefaultStringPiece = NO;
384 [message hasDefaultStringPiece];
386 [message hasDefaultCord];
387 message.hasDefaultCord = NO;
388 [message hasDefaultCord];