GPBPerfTests.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2013 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #import "GPBTestUtilities.h"
  31. #import "google/protobuf/Unittest.pbobjc.h"
  32. #import "google/protobuf/UnittestImport.pbobjc.h"
  33. #import "google/protobuf/UnittestObjc.pbobjc.h"
  34. //
  35. // This file really just uses the unittests framework as a testbed to
  36. // run some simple performance tests. The data can then be used to help
  37. // evaluate changes to the runtime.
  38. //
  39. static const uint32_t kRepeatedCount = 100;
  40. @interface PerfTests : GPBTestCase
  41. @end
  42. @implementation PerfTests
  43. - (void)setUp {
  44. // A convenient place to put a break point if you want to connect instruments.
  45. [super setUp];
  46. }
  47. - (void)testMessagePerformance {
  48. [self measureBlock:^{
  49. for (int i = 0; i < 200; ++i) {
  50. TestAllTypes* message = [[TestAllTypes alloc] init];
  51. [self setAllFields:message repeatedCount:kRepeatedCount];
  52. NSData* rawBytes = [message data];
  53. [message release];
  54. message = [[TestAllTypes alloc] initWithData:rawBytes error:NULL];
  55. [message release];
  56. }
  57. }];
  58. }
  59. - (void)testMessageSerialParsingPerformance {
  60. // This and the next test are meant to monitor that the parsing functionality of protos does not
  61. // lock across threads when parsing different instances. The Serial version of the test should run
  62. // around ~2 times slower than the Parallel version since it's parsing the protos in the same
  63. // thread.
  64. TestAllTypes *allTypesMessage = [TestAllTypes message];
  65. [self setAllFields:allTypesMessage repeatedCount:2];
  66. NSData *allTypesData = allTypesMessage.data;
  67. [self measureBlock:^{
  68. for (int i = 0; i < 500; ++i) {
  69. [TestAllTypes parseFromData:allTypesData error:NULL];
  70. [TestAllTypes parseFromData:allTypesData error:NULL];
  71. }
  72. }];
  73. }
  74. - (void)testMessageParallelParsingPerformance {
  75. // This and the previous test are meant to monitor that the parsing functionality of protos does
  76. // not lock across threads when parsing different instances. The Serial version of the test should
  77. // run around ~2 times slower than the Parallel version since it's parsing the protos in the same
  78. // thread.
  79. TestAllTypes *allTypesMessage = [TestAllTypes message];
  80. [self setAllFields:allTypesMessage repeatedCount:2];
  81. NSData *allTypesData = allTypesMessage.data;
  82. dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
  83. [self measureBlock:^{
  84. for (int i = 0; i < 500; ++i) {
  85. dispatch_group_t group = dispatch_group_create();
  86. dispatch_group_async(group, concurrentQueue, ^{
  87. [TestAllTypes parseFromData:allTypesData error:NULL];
  88. });
  89. dispatch_group_async(group, concurrentQueue, ^{
  90. [TestAllTypes parseFromData:allTypesData error:NULL];
  91. });
  92. dispatch_group_notify(group, concurrentQueue, ^{});
  93. dispatch_release(group);
  94. }
  95. }];
  96. dispatch_release(concurrentQueue);
  97. }
  98. - (void)testMessageSerialExtensionsParsingPerformance {
  99. // This and the next test are meant to monitor that the parsing functionality of protos does not
  100. // lock across threads when parsing different instances when using extensions. The Serial version
  101. // of the test should run around ~2 times slower than the Parallel version since it's parsing the
  102. // protos in the same thread.
  103. TestAllExtensions *allExtensionsMessage = [TestAllExtensions message];
  104. [self setAllExtensions:allExtensionsMessage repeatedCount:2];
  105. NSData *allExtensionsData = allExtensionsMessage.data;
  106. [self measureBlock:^{
  107. for (int i = 0; i < 500; ++i) {
  108. [TestAllExtensions parseFromData:allExtensionsData
  109. extensionRegistry:[self extensionRegistry]
  110. error:NULL];
  111. [TestAllExtensions parseFromData:allExtensionsData
  112. extensionRegistry:[self extensionRegistry]
  113. error:NULL];
  114. }
  115. }];
  116. }
  117. - (void)testMessageParallelExtensionsParsingPerformance {
  118. // This and the previous test are meant to monitor that the parsing functionality of protos does
  119. // not lock across threads when parsing different instances when using extensions. The Serial
  120. // version of the test should run around ~2 times slower than the Parallel version since it's
  121. // parsing the protos in the same thread.
  122. TestAllExtensions *allExtensionsMessage = [TestAllExtensions message];
  123. [self setAllExtensions:allExtensionsMessage repeatedCount:2];
  124. NSData *allExtensionsData = allExtensionsMessage.data;
  125. dispatch_queue_t concurrentQueue = dispatch_queue_create("perfQueue", DISPATCH_QUEUE_CONCURRENT);
  126. [self measureBlock:^{
  127. for (int i = 0; i < 500; ++i) {
  128. dispatch_group_t group = dispatch_group_create();
  129. dispatch_group_async(group, concurrentQueue, ^{
  130. [TestAllExtensions parseFromData:allExtensionsData
  131. extensionRegistry:[UnittestRoot extensionRegistry]
  132. error:NULL];
  133. });
  134. dispatch_group_async(group, concurrentQueue, ^{
  135. [TestAllExtensions parseFromData:allExtensionsData
  136. extensionRegistry:[UnittestRoot extensionRegistry]
  137. error:NULL];
  138. });
  139. dispatch_group_notify(group, concurrentQueue, ^{});
  140. dispatch_release(group);
  141. }
  142. }];
  143. dispatch_release(concurrentQueue);
  144. }
  145. - (void)testExtensionsPerformance {
  146. [self measureBlock:^{
  147. for (int i = 0; i < 200; ++i) {
  148. TestAllExtensions* message = [[TestAllExtensions alloc] init];
  149. [self setAllExtensions:message repeatedCount:kRepeatedCount];
  150. NSData* rawBytes = [message data];
  151. [message release];
  152. TestAllExtensions* message2 =
  153. [[TestAllExtensions alloc] initWithData:rawBytes error:NULL];
  154. [message2 release];
  155. }
  156. }];
  157. }
  158. - (void)testPackedTypesPerformance {
  159. [self measureBlock:^{
  160. for (int i = 0; i < 1000; ++i) {
  161. TestPackedTypes* message = [[TestPackedTypes alloc] init];
  162. [self setPackedFields:message repeatedCount:kRepeatedCount];
  163. NSData* rawBytes = [message data];
  164. [message release];
  165. message = [[TestPackedTypes alloc] initWithData:rawBytes error:NULL];
  166. [message release];
  167. }
  168. }];
  169. }
  170. - (void)testPackedExtensionsPerformance {
  171. [self measureBlock:^{
  172. for (int i = 0; i < 1000; ++i) {
  173. TestPackedExtensions* message = [[TestPackedExtensions alloc] init];
  174. [self setPackedExtensions:message repeatedCount:kRepeatedCount];
  175. NSData* rawBytes = [message data];
  176. [message release];
  177. TestPackedExtensions* message2 =
  178. [[TestPackedExtensions alloc] initWithData:rawBytes error:NULL];
  179. [message2 release];
  180. }
  181. }];
  182. }
  183. - (void)testHas {
  184. TestAllTypes* message = [self allSetRepeatedCount:1];
  185. [self measureBlock:^{
  186. for (int i = 0; i < 10000; ++i) {
  187. [message hasOptionalInt32];
  188. message.hasOptionalInt32 = NO;
  189. [message hasOptionalInt32];
  190. [message hasOptionalInt64];
  191. message.hasOptionalInt64 = NO;
  192. [message hasOptionalInt64];
  193. [message hasOptionalUint32];
  194. message.hasOptionalUint32 = NO;
  195. [message hasOptionalUint32];
  196. [message hasOptionalUint64];
  197. message.hasOptionalUint64 = NO;
  198. [message hasOptionalUint64];
  199. [message hasOptionalSint32];
  200. message.hasOptionalSint32 = NO;
  201. [message hasOptionalSint32];
  202. [message hasOptionalSint64];
  203. message.hasOptionalSint64 = NO;
  204. [message hasOptionalSint64];
  205. [message hasOptionalFixed32];
  206. message.hasOptionalFixed32 = NO;
  207. [message hasOptionalFixed32];
  208. [message hasOptionalFixed64];
  209. message.hasOptionalFixed64 = NO;
  210. [message hasOptionalFixed64];
  211. [message hasOptionalSfixed32];
  212. message.hasOptionalSfixed32 = NO;
  213. [message hasOptionalSfixed32];
  214. [message hasOptionalSfixed64];
  215. message.hasOptionalSfixed64 = NO;
  216. [message hasOptionalSfixed64];
  217. [message hasOptionalFloat];
  218. message.hasOptionalFloat = NO;
  219. [message hasOptionalFloat];
  220. [message hasOptionalDouble];
  221. message.hasOptionalDouble = NO;
  222. [message hasOptionalDouble];
  223. [message hasOptionalBool];
  224. message.hasOptionalBool = NO;
  225. [message hasOptionalBool];
  226. [message hasOptionalString];
  227. message.hasOptionalString = NO;
  228. [message hasOptionalString];
  229. [message hasOptionalBytes];
  230. message.hasOptionalBytes = NO;
  231. [message hasOptionalBytes];
  232. [message hasOptionalGroup];
  233. message.hasOptionalGroup = NO;
  234. [message hasOptionalGroup];
  235. [message hasOptionalNestedMessage];
  236. message.hasOptionalNestedMessage = NO;
  237. [message hasOptionalNestedMessage];
  238. [message hasOptionalForeignMessage];
  239. message.hasOptionalForeignMessage = NO;
  240. [message hasOptionalForeignMessage];
  241. [message hasOptionalImportMessage];
  242. message.hasOptionalImportMessage = NO;
  243. [message hasOptionalImportMessage];
  244. [message.optionalGroup hasA];
  245. message.optionalGroup.hasA = NO;
  246. [message.optionalGroup hasA];
  247. [message.optionalNestedMessage hasBb];
  248. message.optionalNestedMessage.hasBb = NO;
  249. [message.optionalNestedMessage hasBb];
  250. [message.optionalForeignMessage hasC];
  251. message.optionalForeignMessage.hasC = NO;
  252. [message.optionalForeignMessage hasC];
  253. [message.optionalImportMessage hasD];
  254. message.optionalImportMessage.hasD = NO;
  255. [message.optionalImportMessage hasD];
  256. [message hasOptionalNestedEnum];
  257. message.hasOptionalNestedEnum = NO;
  258. [message hasOptionalNestedEnum];
  259. [message hasOptionalForeignEnum];
  260. message.hasOptionalForeignEnum = NO;
  261. [message hasOptionalForeignEnum];
  262. [message hasOptionalImportEnum];
  263. message.hasOptionalImportEnum = NO;
  264. [message hasOptionalImportEnum];
  265. [message hasOptionalStringPiece];
  266. message.hasOptionalStringPiece = NO;
  267. [message hasOptionalStringPiece];
  268. [message hasOptionalCord];
  269. message.hasOptionalCord = NO;
  270. [message hasOptionalCord];
  271. [message hasDefaultInt32];
  272. message.hasDefaultInt32 = NO;
  273. [message hasDefaultInt32];
  274. [message hasDefaultInt64];
  275. message.hasDefaultInt64 = NO;
  276. [message hasDefaultInt64];
  277. [message hasDefaultUint32];
  278. message.hasDefaultUint32 = NO;
  279. [message hasDefaultUint32];
  280. [message hasDefaultUint64];
  281. message.hasDefaultUint64 = NO;
  282. [message hasDefaultUint64];
  283. [message hasDefaultSint32];
  284. message.hasDefaultSint32 = NO;
  285. [message hasDefaultSint32];
  286. [message hasDefaultSint64];
  287. message.hasDefaultSint64 = NO;
  288. [message hasDefaultSint64];
  289. [message hasDefaultFixed32];
  290. message.hasDefaultFixed32 = NO;
  291. [message hasDefaultFixed32];
  292. [message hasDefaultFixed64];
  293. message.hasDefaultFixed64 = NO;
  294. [message hasDefaultFixed64];
  295. [message hasDefaultSfixed32];
  296. message.hasDefaultSfixed32 = NO;
  297. [message hasDefaultSfixed32];
  298. [message hasDefaultSfixed64];
  299. message.hasDefaultSfixed64 = NO;
  300. [message hasDefaultSfixed64];
  301. [message hasDefaultFloat];
  302. message.hasDefaultFloat = NO;
  303. [message hasDefaultFloat];
  304. [message hasDefaultDouble];
  305. message.hasDefaultDouble = NO;
  306. [message hasDefaultDouble];
  307. [message hasDefaultBool];
  308. message.hasDefaultBool = NO;
  309. [message hasDefaultBool];
  310. [message hasDefaultString];
  311. message.hasDefaultString = NO;
  312. [message hasDefaultString];
  313. [message hasDefaultBytes];
  314. message.hasDefaultBytes = NO;
  315. [message hasDefaultBytes];
  316. [message hasDefaultNestedEnum];
  317. message.hasDefaultNestedEnum = NO;
  318. [message hasDefaultNestedEnum];
  319. [message hasDefaultForeignEnum];
  320. message.hasDefaultForeignEnum = NO;
  321. [message hasDefaultForeignEnum];
  322. [message hasDefaultImportEnum];
  323. message.hasDefaultImportEnum = NO;
  324. [message hasDefaultImportEnum];
  325. [message hasDefaultStringPiece];
  326. message.hasDefaultStringPiece = NO;
  327. [message hasDefaultStringPiece];
  328. [message hasDefaultCord];
  329. message.hasDefaultCord = NO;
  330. [message hasDefaultCord];
  331. }
  332. }];
  333. }
  334. @end