Benchmark.m 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. //
  2. // Benchmark.m
  3. // CacheBenchmark
  4. //
  5. // Created by ibireme on 15/10/20.
  6. // Copyright (C) 2015 ibireme. All rights reserved.
  7. //
  8. #import "Benchmark.h"
  9. #import "YYCache.h"
  10. #import "PINCache.h"
  11. #import "YYThreadSafeDictionary.h"
  12. #import <QuartzCore/QuartzCore.h>
  13. @implementation Benchmark
  14. + (void)benchmark {
  15. @autoreleasepool {
  16. [self memoryCacheBenchmark];
  17. }
  18. // You should benchmark data writing first.
  19. // Before benchmark data reading, you should kill the app to avoid disk-in-memory cache.
  20. #define WRITE false
  21. #define READ true
  22. #define RANDOMLY true
  23. #if WRITE
  24. printf("\n\n\nwrite\n");
  25. [self diskCacheClearSmallData];
  26. [self diskCacheClearLargeData];
  27. @autoreleasepool {
  28. [self diskCacheWriteSmallDataBenchmark];
  29. }
  30. @autoreleasepool {
  31. [self diskCacheWriteLargeDataBenchmark];
  32. }
  33. printf("\n\n\nreplace\n");
  34. @autoreleasepool {
  35. [self diskCacheWriteSmallDataBenchmark];
  36. }
  37. @autoreleasepool {
  38. [self diskCacheWriteLargeDataBenchmark];
  39. }
  40. #endif
  41. #if READ
  42. printf("\n\n\nread\n");
  43. @autoreleasepool {
  44. [self diskCacheReadSmallDataBenchmark:RANDOMLY];
  45. }
  46. @autoreleasepool {
  47. [self diskCacheReadLargeDataBenchmark:RANDOMLY];
  48. }
  49. printf("\n\n\nread again (with file-in-memory cache)\n");
  50. @autoreleasepool {
  51. [self diskCacheReadSmallDataBenchmark:RANDOMLY];
  52. }
  53. @autoreleasepool {
  54. [self diskCacheReadLargeDataBenchmark:RANDOMLY];
  55. }
  56. printf("\n\n\nread none exist\n");
  57. @autoreleasepool {
  58. [self diskCacheReadSmallDataNoneExist];
  59. }
  60. @autoreleasepool {
  61. [self diskCacheReadLargeDataNoneExist];
  62. }
  63. #endif
  64. printf("\n\n--fin--\n\n");
  65. }
  66. + (void)memoryCacheBenchmark {
  67. // 1.27 1.09
  68. // 2.86 5.57
  69. NSMutableDictionary *nsDict = [NSMutableDictionary new];
  70. YYThreadSafeDictionary *nsDictLock = [YYThreadSafeDictionary new];
  71. NSCache *ns = [NSCache new];
  72. PINMemoryCache *pin = [PINMemoryCache new];
  73. YYMemoryCache *yy = [YYMemoryCache new];
  74. NSMutableArray *keys = [NSMutableArray new];
  75. NSMutableArray *values = [NSMutableArray new];
  76. int count = 200000;
  77. for (int i = 0; i < count; i++) {
  78. NSObject *key;
  79. key = @(i); // avoid string compare
  80. //key = @(i).description; // it will slow down NSCache...
  81. //key = [NSUUID UUID].UUIDString;
  82. NSData *value = [NSData dataWithBytes:&i length:sizeof(int)];
  83. [keys addObject:key];
  84. [values addObject:value];
  85. }
  86. NSTimeInterval begin, end, time;
  87. printf("\n===========================\n");
  88. printf("Memory cache set 200000 key-value pairs\n");
  89. begin = CACurrentMediaTime();
  90. @autoreleasepool {
  91. for (int i = 0; i < count; i++) {
  92. [nsDict setObject:values[i] forKey:keys[i]];
  93. }
  94. }
  95. end = CACurrentMediaTime();
  96. time = end - begin;
  97. printf("NSDictionary: %8.2f\n", time * 1000);
  98. begin = CACurrentMediaTime();
  99. @autoreleasepool {
  100. for (int i = 0; i < count; i++) {
  101. [nsDictLock setObject:values[i] forKey:keys[i]];
  102. }
  103. }
  104. end = CACurrentMediaTime();
  105. time = end - begin;
  106. printf("NSDict+Lock: %8.2f\n", time * 1000);
  107. begin = CACurrentMediaTime();
  108. @autoreleasepool {
  109. for (int i = 0; i < count; i++) {
  110. [yy setObject:values[i] forKey:keys[i]];
  111. }
  112. }
  113. end = CACurrentMediaTime();
  114. time = end - begin;
  115. printf("YYMemoryCache: %8.2f\n", time * 1000);
  116. begin = CACurrentMediaTime();
  117. @autoreleasepool {
  118. for (int i = 0; i < count; i++) {
  119. [pin setObject:values[i] forKey:keys[i]];
  120. }
  121. }
  122. end = CACurrentMediaTime();
  123. time = end - begin;
  124. printf("PINMemoryCache: %8.2f\n", time * 1000);
  125. begin = CACurrentMediaTime();
  126. @autoreleasepool {
  127. for (int i = 0; i < count; i++) {
  128. [ns setObject:values[i] forKey:keys[i]];
  129. }
  130. }
  131. end = CACurrentMediaTime();
  132. time = end - begin;
  133. printf("NSCache: %8.2f\n", time * 1000);
  134. printf("\n===========================\n");
  135. printf("Memory cache set 200000 key-value pairs without resize\n");
  136. [nsDict removeAllObjects];
  137. begin = CACurrentMediaTime();
  138. @autoreleasepool {
  139. for (int i = 0; i < count; i++) {
  140. [nsDict setObject:values[i] forKey:keys[i]];
  141. }
  142. }
  143. end = CACurrentMediaTime();
  144. time = end - begin;
  145. printf("NSDictionary: %8.2f\n", time * 1000);
  146. [nsDictLock removeAllObjects];
  147. begin = CACurrentMediaTime();
  148. @autoreleasepool {
  149. for (int i = 0; i < count; i++) {
  150. [nsDictLock setObject:values[i] forKey:keys[i]];
  151. }
  152. }
  153. end = CACurrentMediaTime();
  154. time = end - begin;
  155. printf("NSDict+Lock: %8.2f\n", time * 1000);
  156. //[yy removeAllObjects]; // it will rebuild inner cache...
  157. for (id key in keys) [yy removeObjectForKey:key]; // slow than 'removeAllObjects'
  158. begin = CACurrentMediaTime();
  159. @autoreleasepool {
  160. for (int i = 0; i < count; i++) {
  161. [yy setObject:values[i] forKey:keys[i]];
  162. }
  163. }
  164. end = CACurrentMediaTime();
  165. time = end - begin;
  166. printf("YYMemoryCache: %8.2f\n", time * 1000);
  167. [pin removeAllObjects];
  168. begin = CACurrentMediaTime();
  169. @autoreleasepool {
  170. for (int i = 0; i < count; i++) {
  171. [pin setObject:values[i] forKey:keys[i]];
  172. }
  173. }
  174. end = CACurrentMediaTime();
  175. time = end - begin;
  176. printf("PINMemoryCache: %8.2f\n", time * 1000);
  177. [ns removeAllObjects];
  178. begin = CACurrentMediaTime();
  179. @autoreleasepool {
  180. for (int i = 0; i < count; i++) {
  181. [ns setObject:values[i] forKey:keys[i]];
  182. }
  183. }
  184. end = CACurrentMediaTime();
  185. time = end - begin;
  186. printf("NSCache: %8.2f\n", time * 1000);
  187. printf("\n===========================\n");
  188. printf("Memory cache get 200000 key-value pairs\n");
  189. begin = CACurrentMediaTime();
  190. @autoreleasepool {
  191. for (int i = 0; i < count; i++) {
  192. [nsDict objectForKey:keys[i]];
  193. }
  194. }
  195. end = CACurrentMediaTime();
  196. time = end - begin;
  197. printf("NSDictionary: %8.2f\n", time * 1000);
  198. begin = CACurrentMediaTime();
  199. @autoreleasepool {
  200. for (int i = 0; i < count; i++) {
  201. [nsDictLock objectForKey:keys[i]];
  202. }
  203. }
  204. end = CACurrentMediaTime();
  205. time = end - begin;
  206. printf("NSDict+Lock: %8.2f\n", time * 1000);
  207. begin = CACurrentMediaTime();
  208. @autoreleasepool {
  209. for (int i = 0; i < count; i++) {
  210. [yy objectForKey:keys[i]];
  211. }
  212. }
  213. end = CACurrentMediaTime();
  214. time = end - begin;
  215. printf("YYMemoryCache: %8.2f\n", time * 1000);
  216. begin = CACurrentMediaTime();
  217. @autoreleasepool {
  218. for (int i = 0; i < count; i++) {
  219. [pin objectForKey:keys[i]];
  220. }
  221. }
  222. end = CACurrentMediaTime();
  223. time = end - begin;
  224. printf("PINMemoryCache: %8.2f\n", time * 1000);
  225. begin = CACurrentMediaTime();
  226. @autoreleasepool {
  227. for (int i = 0; i < count; i++) {
  228. [ns objectForKey:keys[i]];
  229. }
  230. }
  231. end = CACurrentMediaTime();
  232. time = end - begin;
  233. printf("NSCache: %8.2f\n", time * 1000);
  234. printf("\n===========================\n");
  235. printf("Memory cache get 100000 key-value pairs randomly\n");
  236. for (NSUInteger i = keys.count; i > 1; i--) {
  237. [keys exchangeObjectAtIndex:(i - 1) withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
  238. }
  239. begin = CACurrentMediaTime();
  240. @autoreleasepool {
  241. for (int i = 0; i < count; i++) {
  242. [nsDict objectForKey:keys[i]];
  243. }
  244. }
  245. end = CACurrentMediaTime();
  246. time = end - begin;
  247. printf("NSDictionary: %8.2f\n", time * 1000);
  248. begin = CACurrentMediaTime();
  249. @autoreleasepool {
  250. for (int i = 0; i < count; i++) {
  251. [nsDictLock objectForKey:keys[i]];
  252. }
  253. }
  254. end = CACurrentMediaTime();
  255. time = end - begin;
  256. printf("NSDict+Lock: %8.2f\n", time * 1000);
  257. begin = CACurrentMediaTime();
  258. @autoreleasepool {
  259. for (int i = 0; i < count; i++) {
  260. [yy objectForKey:keys[i]];
  261. }
  262. }
  263. end = CACurrentMediaTime();
  264. time = end - begin;
  265. printf("YYMemoryCache: %8.2f\n", time * 1000);
  266. begin = CACurrentMediaTime();
  267. @autoreleasepool {
  268. for (int i = 0; i < count; i++) {
  269. [pin objectForKey:keys[i]];
  270. }
  271. }
  272. end = CACurrentMediaTime();
  273. time = end - begin;
  274. printf("PINMemoryCache: %8.2f\n", time * 1000);
  275. begin = CACurrentMediaTime();
  276. @autoreleasepool {
  277. for (int i = 0; i < count; i++) {
  278. [ns objectForKey:keys[i]];
  279. }
  280. }
  281. end = CACurrentMediaTime();
  282. time = end - begin;
  283. printf("NSCache: %8.2f\n", time * 1000);
  284. printf("\n===========================\n");
  285. printf("Memory cache get 200000 key-value pairs none exist\n");
  286. for (int i = 0; i < count; i++) {
  287. NSObject *key;
  288. key = @(i + count); // avoid string compare
  289. [keys addObject:key];
  290. }
  291. for (NSUInteger i = keys.count; i > 1; i--) {
  292. [keys exchangeObjectAtIndex:(i - 1) withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
  293. }
  294. begin = CACurrentMediaTime();
  295. @autoreleasepool {
  296. for (int i = 0; i < count; i++) {
  297. [nsDict objectForKey:keys[i]];
  298. }
  299. }
  300. end = CACurrentMediaTime();
  301. time = end - begin;
  302. printf("NSDictionary: %8.2f\n", time * 1000);
  303. begin = CACurrentMediaTime();
  304. @autoreleasepool {
  305. for (int i = 0; i < count; i++) {
  306. [nsDictLock objectForKey:keys[i]];
  307. }
  308. }
  309. end = CACurrentMediaTime();
  310. time = end - begin;
  311. printf("NSDict+Lock: %8.2f\n", time * 1000);
  312. begin = CACurrentMediaTime();
  313. @autoreleasepool {
  314. for (int i = 0; i < count; i++) {
  315. [yy objectForKey:keys[i]];
  316. }
  317. }
  318. end = CACurrentMediaTime();
  319. time = end - begin;
  320. printf("YYMemoryCache: %8.2f\n", time * 1000);
  321. begin = CACurrentMediaTime();
  322. @autoreleasepool {
  323. for (int i = 0; i < count; i++) {
  324. [pin objectForKey:keys[i]];
  325. }
  326. }
  327. end = CACurrentMediaTime();
  328. time = end - begin;
  329. printf("PINMemoryCache: %8.2f\n", time * 1000);
  330. begin = CACurrentMediaTime();
  331. @autoreleasepool {
  332. for (int i = 0; i < count; i++) {
  333. [ns objectForKey:keys[i]];
  334. }
  335. }
  336. end = CACurrentMediaTime();
  337. time = end - begin;
  338. printf("NSCache: %8.2f\n", time * 1000);
  339. }
  340. + (void)diskCacheClearSmallData {
  341. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  342. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkSmall"];
  343. [[NSFileManager defaultManager] removeItemAtPath:basePath error:nil];
  344. }
  345. + (void)diskCacheClearLargeData {
  346. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  347. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkLarge"];
  348. [[NSFileManager defaultManager] removeItemAtPath:basePath error:nil];
  349. }
  350. + (void)diskCacheWriteSmallDataBenchmark {
  351. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  352. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkSmall"];
  353. YYKVStorage *yykvFile = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvFile"] type:YYKVStorageTypeFile];
  354. YYKVStorage *yykvSQLite = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvSQLite"] type:YYKVStorageTypeSQLite];
  355. YYDiskCache *yy = [[YYDiskCache alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yy"]];
  356. PINDiskCache *pin = [[PINDiskCache alloc] initWithName:@"pin" rootPath:[basePath stringByAppendingPathComponent:@"pin"]];
  357. int count = 1000;
  358. NSMutableArray *keys = [NSMutableArray new];
  359. NSMutableArray *values = [NSMutableArray new];
  360. for (int i = 0; i < count; i++) {
  361. NSString *key = @(i).description;
  362. NSNumber *value = @(i);
  363. [keys addObject:key];
  364. [values addObject:value];
  365. }
  366. NSTimeInterval begin, end, time;
  367. printf("\n===========================\n");
  368. printf("Disk cache set 1000 key-value pairs (value is NSNumber)\n");
  369. begin = CACurrentMediaTime();
  370. @autoreleasepool {
  371. for (int i = 0; i < count; i++) {
  372. [yykvFile saveItemWithKey:keys[i] value:[NSKeyedArchiver archivedDataWithRootObject:values[i]] filename:keys[i] extendedData:nil];
  373. }
  374. }
  375. end = CACurrentMediaTime();
  376. time = end - begin;
  377. printf("YYKVFile: %8.2f\n", time * 1000);
  378. begin = CACurrentMediaTime();
  379. @autoreleasepool {
  380. for (int i = 0; i < count; i++) {
  381. [yykvSQLite saveItemWithKey:keys[i] value:[NSKeyedArchiver archivedDataWithRootObject:values[i]]];
  382. }
  383. }
  384. end = CACurrentMediaTime();
  385. time = end - begin;
  386. printf("YYKVSQLite: %8.2f\n", time * 1000);
  387. begin = CACurrentMediaTime();
  388. @autoreleasepool {
  389. for (int i = 0; i < count; i++) {
  390. [yy setObject:values[i] forKey:keys[i]];
  391. }
  392. }
  393. end = CACurrentMediaTime();
  394. time = end - begin;
  395. printf("YYDiskCache: %8.2f\n", time * 1000);
  396. begin = CACurrentMediaTime();
  397. @autoreleasepool {
  398. for (int i = 0; i < count; i++) {
  399. [pin setObject:values[i] forKey:keys[i]];
  400. }
  401. }
  402. end = CACurrentMediaTime();
  403. time = end - begin;
  404. printf("PINDiskCache: %8.2f\n", time * 1000);
  405. }
  406. + (void)diskCacheWriteLargeDataBenchmark {
  407. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  408. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkLarge"];
  409. YYKVStorage *yykvFile = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvFile"] type:YYKVStorageTypeFile];
  410. YYKVStorage *yykvSQLite = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvSQLite"] type:YYKVStorageTypeSQLite];
  411. YYDiskCache *yy = [[YYDiskCache alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yy"]];
  412. yy.customArchiveBlock = ^(id object) {return object;};
  413. yy.customUnarchiveBlock = ^(NSData *object) {return object;};
  414. PINDiskCache *pin = [[PINDiskCache alloc] initWithName:@"pin" rootPath:[basePath stringByAppendingPathComponent:@"pin"]];
  415. int count = 1000;
  416. NSMutableArray *keys = [NSMutableArray new];
  417. for (int i = 0; i < count; i++) {
  418. NSString *key = @(i).description;
  419. [keys addObject:key];
  420. }
  421. NSMutableData *dataValue = [NSMutableData new]; // 32KB
  422. for (int i = 0; i < 100 * 1024; i++) {
  423. [dataValue appendBytes:&i length:1];
  424. }
  425. NSTimeInterval begin, end, time;
  426. printf("\n===========================\n");
  427. printf("Disk cache set 1000 key-value pairs (value is NSData(100KB))\n");
  428. begin = CACurrentMediaTime();
  429. @autoreleasepool {
  430. for (int i = 0; i < count; i++) {
  431. [yykvFile saveItemWithKey:keys[i] value:dataValue filename:keys[i] extendedData:nil];
  432. }
  433. }
  434. end = CACurrentMediaTime();
  435. time = end - begin;
  436. printf("YYKVFile: %8.2f\n", time * 1000);
  437. begin = CACurrentMediaTime();
  438. @autoreleasepool {
  439. for (int i = 0; i < count; i++) {
  440. [yykvSQLite saveItemWithKey:keys[i] value:dataValue];
  441. }
  442. }
  443. end = CACurrentMediaTime();
  444. time = end - begin;
  445. printf("YYKVSQLite: %8.2f\n", time * 1000);
  446. begin = CACurrentMediaTime();
  447. @autoreleasepool {
  448. for (int i = 0; i < count; i++) {
  449. [yy setObject:dataValue forKey:keys[i]];
  450. }
  451. }
  452. end = CACurrentMediaTime();
  453. time = end - begin;
  454. printf("YYDiskCache: %8.2f\n", time * 1000);
  455. begin = CACurrentMediaTime();
  456. @autoreleasepool {
  457. for (int i = 0; i < count; i++) {
  458. [pin setObject:dataValue forKey:keys[i]];
  459. }
  460. }
  461. end = CACurrentMediaTime();
  462. time = end - begin;
  463. printf("PINDiskCache: %8.2f\n", time * 1000);
  464. }
  465. + (void)diskCacheReadSmallDataBenchmark:(BOOL)randomly {
  466. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  467. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkSmall"];
  468. YYKVStorage *yykvFile = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvFile"] type:YYKVStorageTypeFile];
  469. YYKVStorage *yykvSQLite = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvSQLite"] type:YYKVStorageTypeSQLite];
  470. YYDiskCache *yy = [[YYDiskCache alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yy"]];
  471. PINDiskCache *pin = [[PINDiskCache alloc] initWithName:@"pin" rootPath:[basePath stringByAppendingPathComponent:@"pin"]];
  472. int count = 1000;
  473. NSMutableArray *keys = [NSMutableArray new];
  474. for (int i = 0; i < count; i++) {
  475. NSString *key = @(i).description;
  476. [keys addObject:key];
  477. }
  478. if (randomly) {
  479. for (NSUInteger i = keys.count; i > 1; i--) {
  480. [keys exchangeObjectAtIndex:(i - 1) withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
  481. }
  482. }
  483. NSTimeInterval begin, end, time;
  484. printf("\n===========================\n");
  485. printf("Disk cache get 1000 key-value pairs %s(value is NSNumber)\n", (randomly ? "randomly " : ""));
  486. begin = CACurrentMediaTime();
  487. @autoreleasepool {
  488. for (int i = 0; i < count; i++) {
  489. YYKVStorageItem *item = [yykvFile getItemForKey:keys[i]];
  490. NSNumber *value = [NSKeyedUnarchiver unarchiveObjectWithData:item.value];
  491. if (!value) printf("error!");
  492. }
  493. }
  494. end = CACurrentMediaTime();
  495. time = end - begin;
  496. printf("YYKVFile: %8.2f\n", time * 1000);
  497. begin = CACurrentMediaTime();
  498. @autoreleasepool {
  499. for (int i = 0; i < count; i++) {
  500. YYKVStorageItem *item = [yykvSQLite getItemForKey:keys[i]];
  501. NSNumber *value = [NSKeyedUnarchiver unarchiveObjectWithData:item.value];
  502. if (!value) printf("error!");
  503. }
  504. }
  505. end = CACurrentMediaTime();
  506. time = end - begin;
  507. printf("YYKVSQLite: %8.2f\n", time * 1000);
  508. begin = CACurrentMediaTime();
  509. @autoreleasepool {
  510. for (int i = 0; i < count; i++) {
  511. NSNumber *value = (id)[yy objectForKey:keys[i]];
  512. if (!value) printf("error!");
  513. }
  514. }
  515. end = CACurrentMediaTime();
  516. time = end - begin;
  517. printf("YYDiskCache: %8.2f\n", time * 1000);
  518. begin = CACurrentMediaTime();
  519. @autoreleasepool {
  520. for (int i = 0; i < count; i++) {
  521. NSNumber *value = (id)[pin objectForKey:keys[i]];
  522. if (!value) printf("error!");
  523. }
  524. }
  525. end = CACurrentMediaTime();
  526. time = end - begin;
  527. printf("PINDiskCache: %8.2f\n", time * 1000);
  528. }
  529. + (void)diskCacheReadLargeDataBenchmark:(BOOL)randomly {
  530. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  531. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkLarge"];
  532. YYKVStorage *yykvFile = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvFile"] type:YYKVStorageTypeFile];
  533. YYKVStorage *yykvSQLite = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvSQLite"] type:YYKVStorageTypeSQLite];
  534. YYDiskCache *yy = [[YYDiskCache alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yy"]];
  535. yy.customArchiveBlock = ^(id object) {return object;};
  536. yy.customUnarchiveBlock = ^(NSData *object) {return object;};
  537. PINDiskCache *pin = [[PINDiskCache alloc] initWithName:@"pin" rootPath:[basePath stringByAppendingPathComponent:@"pin"]];
  538. int count = 1000;
  539. NSMutableArray *keys = [NSMutableArray new];
  540. for (int i = 0; i < count; i++) {
  541. NSString *key = @(i).description;
  542. [keys addObject:key];
  543. }
  544. if (randomly) {
  545. for (NSUInteger i = keys.count; i > 1; i--) {
  546. [keys exchangeObjectAtIndex:(i - 1) withObjectAtIndex:arc4random_uniform((u_int32_t)i)];
  547. }
  548. }
  549. NSTimeInterval begin, end, time;
  550. printf("\n===========================\n");
  551. printf("Disk cache get 1000 key-value pairs %s(value is NSData(100KB))\n", (randomly ? "randomly " : ""));
  552. begin = CACurrentMediaTime();
  553. @autoreleasepool {
  554. for (int i = 0; i < count; i++) {
  555. YYKVStorageItem *item = [yykvFile getItemForKey:keys[i]];
  556. NSData *value = item.value;
  557. if (!value) printf("error!");
  558. }
  559. }
  560. end = CACurrentMediaTime();
  561. time = end - begin;
  562. printf("YYKVFile: %8.2f\n", time * 1000);
  563. begin = CACurrentMediaTime();
  564. @autoreleasepool {
  565. for (int i = 0; i < count; i++) {
  566. YYKVStorageItem *item = [yykvSQLite getItemForKey:keys[i]];
  567. NSData *value = item.value;
  568. if (!value) printf("error!");
  569. }
  570. }
  571. end = CACurrentMediaTime();
  572. time = end - begin;
  573. printf("YYKVSQLite: %8.2f\n", time * 1000);
  574. begin = CACurrentMediaTime();
  575. @autoreleasepool {
  576. for (int i = 0; i < count; i++) {
  577. NSData *value = (id)[yy objectForKey:keys[i]];
  578. if (!value) printf("error!");
  579. }
  580. }
  581. end = CACurrentMediaTime();
  582. time = end - begin;
  583. printf("YYDiskCache: %8.2f\n", time * 1000);
  584. begin = CACurrentMediaTime();
  585. @autoreleasepool {
  586. for (int i = 0; i < count; i++) {
  587. NSData *value = (id)[pin objectForKey:keys[i]];
  588. if (!value) printf("error!");
  589. }
  590. }
  591. end = CACurrentMediaTime();
  592. time = end - begin;
  593. printf("PINDiskCache: %8.2f\n", time * 1000);
  594. }
  595. + (void)diskCacheReadSmallDataNoneExist {
  596. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  597. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkSmall"];
  598. YYKVStorage *yykvFile = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvFile"] type:YYKVStorageTypeFile];
  599. YYKVStorage *yykvSQLite = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvSQLite"] type:YYKVStorageTypeSQLite];
  600. YYDiskCache *yy = [[YYDiskCache alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yy"]];
  601. PINDiskCache *pin = [[PINDiskCache alloc] initWithName:@"pin" rootPath:[basePath stringByAppendingPathComponent:@"pin"]];
  602. int count = 1000;
  603. NSMutableArray *keys = [NSMutableArray new];
  604. for (int i = 0; i < count; i++) {
  605. NSString *key = @(i + count).description;
  606. [keys addObject:key];
  607. }
  608. NSTimeInterval begin, end, time;
  609. printf("\n===========================\n");
  610. printf("Disk cache get 1000 key-value pairs none exist\n");
  611. begin = CACurrentMediaTime();
  612. @autoreleasepool {
  613. for (int i = 0; i < count; i++) {
  614. YYKVStorageItem *item = [yykvFile getItemForKey:keys[i]];
  615. if (item.value) printf("error!");
  616. }
  617. }
  618. end = CACurrentMediaTime();
  619. time = end - begin;
  620. printf("YYKVFile: %8.2f\n", time * 1000);
  621. begin = CACurrentMediaTime();
  622. @autoreleasepool {
  623. for (int i = 0; i < count; i++) {
  624. YYKVStorageItem *item = [yykvSQLite getItemForKey:keys[i]];
  625. if (item.value) printf("error!");
  626. }
  627. }
  628. end = CACurrentMediaTime();
  629. time = end - begin;
  630. printf("YYKVSQLite: %8.2f\n", time * 1000);
  631. begin = CACurrentMediaTime();
  632. @autoreleasepool {
  633. for (int i = 0; i < count; i++) {
  634. NSNumber *value = (id)[yy objectForKey:keys[i]];
  635. if (value) printf("error!");
  636. }
  637. }
  638. end = CACurrentMediaTime();
  639. time = end - begin;
  640. printf("YYDiskCache: %8.2f\n", time * 1000);
  641. begin = CACurrentMediaTime();
  642. @autoreleasepool {
  643. for (int i = 0; i < count; i++) {
  644. NSNumber *value = (id)[pin objectForKey:keys[i]];
  645. if (value) printf("error!");
  646. }
  647. }
  648. end = CACurrentMediaTime();
  649. time = end - begin;
  650. printf("PINDiskCache: %8.2f\n", time * 1000);
  651. }
  652. + (void)diskCacheReadLargeDataNoneExist {
  653. NSString *basePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) firstObject];
  654. basePath = [basePath stringByAppendingPathComponent:@"FileCacheBenchmarkLarge"];
  655. YYKVStorage *yykvFile = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvFile"] type:YYKVStorageTypeFile];
  656. YYKVStorage *yykvSQLite = [[YYKVStorage alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yykvSQLite"] type:YYKVStorageTypeSQLite];
  657. YYDiskCache *yy = [[YYDiskCache alloc] initWithPath:[basePath stringByAppendingPathComponent:@"yy"]];
  658. yy.customArchiveBlock = ^(id object) {return object;};
  659. yy.customUnarchiveBlock = ^(NSData *object) {return object;};
  660. PINDiskCache *pin = [[PINDiskCache alloc] initWithName:@"pin" rootPath:[basePath stringByAppendingPathComponent:@"pin"]];
  661. int count = 1000;
  662. NSMutableArray *keys = [NSMutableArray new];
  663. for (int i = 0; i < count; i++) {
  664. NSString *key = @(i + count).description;
  665. [keys addObject:key];
  666. }
  667. NSTimeInterval begin, end, time;
  668. printf("\n===========================\n");
  669. printf("Disk cache get 1000 key-value pairs none exist\n");
  670. begin = CACurrentMediaTime();
  671. @autoreleasepool {
  672. for (int i = 0; i < count; i++) {
  673. YYKVStorageItem *item = [yykvFile getItemForKey:keys[i]];
  674. if (item.value) printf("error!");
  675. }
  676. }
  677. end = CACurrentMediaTime();
  678. time = end - begin;
  679. printf("YYKVFile: %8.2f\n", time * 1000);
  680. begin = CACurrentMediaTime();
  681. @autoreleasepool {
  682. for (int i = 0; i < count; i++) {
  683. YYKVStorageItem *item = [yykvSQLite getItemForKey:keys[i]];
  684. if (item.value) printf("error!");
  685. }
  686. }
  687. end = CACurrentMediaTime();
  688. time = end - begin;
  689. printf("YYKVSQLite: %8.2f\n", time * 1000);
  690. begin = CACurrentMediaTime();
  691. @autoreleasepool {
  692. for (int i = 0; i < count; i++) {
  693. NSData *value = (id)[yy objectForKey:keys[i]];
  694. if (value) printf("error!");
  695. }
  696. }
  697. end = CACurrentMediaTime();
  698. time = end - begin;
  699. printf("YYDiskCache: %8.2f\n", time * 1000);
  700. begin = CACurrentMediaTime();
  701. @autoreleasepool {
  702. for (int i = 0; i < count; i++) {
  703. NSData *value = (id)[pin objectForKey:keys[i]];
  704. if (value) printf("error!");
  705. }
  706. }
  707. end = CACurrentMediaTime();
  708. time = end - begin;
  709. printf("PINDiskCache: %8.2f\n", time * 1000);
  710. }
  711. @end