RyanJsonMemoryFootprintTest.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #include "RyanJsonTest.h"
  2. static void *yy_malloc(void *ctx, size_t size)
  3. {
  4. (void)(ctx);
  5. return v_malloc_tlsf(size);
  6. }
  7. static void *yy_realloc(void *ctx, void *ptr, size_t oldSize, size_t size)
  8. {
  9. (void)(ctx);
  10. (void)(oldSize);
  11. return v_realloc_tlsf(ptr, size);
  12. }
  13. static void yy_free(void *ctx, void *ptr)
  14. {
  15. (void)(ctx);
  16. v_free_tlsf(ptr);
  17. }
  18. static RyanJsonBool_e RyanJsonMemoryFootprint(char *jsonstr, int32_t *footprint)
  19. {
  20. int32_t use = vallocGetUseByTlsf();
  21. RyanJsonInitHooks(v_malloc_tlsf, v_free_tlsf, v_realloc_tlsf);
  22. RyanJson_t json = RyanJsonParse(jsonstr);
  23. RyanJsonCheckCode(NULL != json, {
  24. printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
  25. return RyanJsonFalse;
  26. });
  27. use = vallocGetUseByTlsf() - use;
  28. RyanJsonDelete(json);
  29. *footprint = use;
  30. return RyanJsonTrue;
  31. }
  32. static RyanJsonBool_e cJSONMemoryFootprint(char *jsonstr, int32_t *footprint)
  33. {
  34. int32_t use = vallocGetUseByTlsf();
  35. cJSON_Hooks hooks = {.malloc_fn = v_malloc_tlsf, .free_fn = v_free_tlsf};
  36. cJSON_InitHooks(&hooks);
  37. cJSON *json = cJSON_Parse(jsonstr);
  38. RyanJsonCheckCode(NULL != json, {
  39. printf("%s:%d 解析失败\r\n", __FILE__, __LINE__);
  40. return RyanJsonFalse;
  41. });
  42. use = vallocGetUseByTlsf() - use;
  43. cJSON_Delete(json);
  44. *footprint = use;
  45. return RyanJsonTrue;
  46. }
  47. static RyanJsonBool_e yyjsonMemoryFootprint(char *jsonstr, int32_t *footprint)
  48. {
  49. static yyjson_alc yyalc = {yy_malloc, yy_realloc, yy_free, NULL};
  50. int32_t use = vallocGetUseByTlsf();
  51. // 先解析成只读文档(可用自定义分配器 yyalc)
  52. yyjson_doc *doc = yyjson_read_opts(jsonstr, strlen(jsonstr), YYJSON_READ_NOFLAG, &yyalc, NULL);
  53. RyanJsonCheckReturnFalse(NULL != doc);
  54. // 从只读文档拷贝为可变文档(用于后续读写修改)
  55. yyjson_mut_doc *mdoc = yyjson_doc_mut_copy(doc, &yyalc);
  56. yyjson_doc_free(doc);
  57. RyanJsonCheckReturnFalse(NULL != mdoc);
  58. // 统计当前分配器的占用
  59. use = vallocGetUseByTlsf() - use;
  60. // 用完释放可变文档
  61. yyjson_mut_doc_free(mdoc);
  62. *footprint = use;
  63. return RyanJsonTrue;
  64. }
  65. static RyanJsonBool_e printfJsonCompare(char *jsonstr)
  66. {
  67. int32_t RyanJsonCount = 0;
  68. int32_t cJSONCount = 0;
  69. int32_t yyjsonCount = 0;
  70. RyanJsonBool_e status = RyanJsonFalse;
  71. status = RyanJsonMemoryFootprint(jsonstr, &RyanJsonCount);
  72. RyanJsonCheckReturnFalse(RyanJsonTrue == status);
  73. status = cJSONMemoryFootprint(jsonstr, &cJSONCount);
  74. RyanJsonCheckReturnFalse(RyanJsonTrue == status);
  75. status = yyjsonMemoryFootprint(jsonstr, &yyjsonCount);
  76. RyanJsonCheckReturnFalse(RyanJsonTrue == status);
  77. printf("json原始文本长度为 %ld, 序列化后RyanJson内存占用: %d, cJSON内存占用: %d, yyjson内存占用: %d\r\n", strlen(jsonstr),
  78. RyanJsonCount, cJSONCount, yyjsonCount);
  79. double save_vs_cjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)cJSONCount;
  80. double save_vs_yyjson = 100.0 - ((double)RyanJsonCount * 100.0) / (double)yyjsonCount;
  81. printf("比cJSON节省: %.2f%% 内存占用, 比yyjson节省: %.2f%% 内存占用\r\n", save_vs_cjson, save_vs_yyjson);
  82. return RyanJsonTrue;
  83. }
  84. static RyanJsonBool_e testMixedJsonMemory(void)
  85. {
  86. char *jsonstr =
  87. "{\"item1\":{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,"
  88. "\"item\":{\"inter\":16,"
  89. "\"double\":16.89,\"string\":\"hello\","
  90. "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,"
  91. "16.89,16.89],"
  92. "\"arrayString\":[\"hello\",\"hello\",\"hello\","
  93. "\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null],\"arrayItem\":[{\"inter\":16,\"double\":16.89,"
  94. "\"string\":\"hello\","
  95. "\"boolTrue\":true,\"boolFalse\":false,"
  96. "\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}]"
  97. "},\"item2\":{"
  98. "\"inter\":16,\"double\":16.89,\"string\":"
  99. "\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":{\"inter\":16,\"double\":16.89,\"string\":"
  100. "\"hello\",\"boolTrue\":"
  101. "true,\"boolFalse\":false,\"null\":null},"
  102. "\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89],\"arrayString\":[\"hello\",\"hello\","
  103. "\"hello\",\"hello\","
  104. "\"hello\"],\"array\":[16,16.89,\"hello\","
  105. "true,false,null],\"arrayItem\":[{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":"
  106. "false,\"null\":null},{"
  107. "\"inter\":16,\"double\":16.89,\"string\":"
  108. "\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}]},\"item3\":{\"inter\":16,\"double\":16.89,\"string\":"
  109. "\"hello\",\"boolTrue\":"
  110. "true,\"boolFalse\":false,\"null\":null,"
  111. "\"item\":{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null},"
  112. "\"arrayInt\":[16,16,16,16,"
  113. "16],\"arrayDouble\":[16.89,16.89,16.89,"
  114. "16.89,16.89],\"arrayString\":[\"hello\",\"hello\",\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,"
  115. "false,null],"
  116. "\"arrayItem\":[{\"inter\":16,\"double\":16.89,"
  117. "\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":"
  118. "\"hello\",\"boolTrue\":"
  119. "true,\"boolFalse\":false,\"null\":null}]}"
  120. ",\"item4\":{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,"
  121. "\"item\":{\"inter\":16,"
  122. "\"double\":16.89,\"string\":\"hello\","
  123. "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,"
  124. "16.89,16.89],"
  125. "\"arrayString\":[\"hello\",\"hello\",\"hello\","
  126. "\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null],\"arrayItem\":[{\"inter\":16,\"double\":16.89,"
  127. "\"string\":\"hello\","
  128. "\"boolTrue\":true,\"boolFalse\":false,"
  129. "\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}]"
  130. "}}";
  131. return printfJsonCompare(jsonstr);
  132. }
  133. static RyanJsonBool_e testObjectJsonMemory(void)
  134. {
  135. char *jsonstr =
  136. "{\"message\":\"success感谢又拍云(upyun.com)提供CDN赞助\",\"status\":200,\"date\":\"20230822\",\"time\":\"2023-08-22 "
  137. "09:44:54\",\"cityInfo\":{\"city\":\"郑州市\",\"citykey\":\"101180101\",\"parent\":\"河南\",\"updateTime\":\"07:46\"},"
  138. "\"data\":{\"shidu\":"
  139. "\"85%\",\"pm25\":20,\"pm10\":56,"
  140. "\"quality\":\"良\",\"wendu\":\"29\",\"ganmao\":\"极少数敏感人群应减少户外活动\",\"forecast\":[{\"date\":\"22\",\"high\":"
  141. "\"高温 "
  142. "35℃\",\"low\":\"低温 "
  143. "23℃\",\"ymd\":\"2023-08-22\",\"week\":\"星期二\",\"sunrise\":\"05:51\",\"sunset\":\"19:05\",\"aqi\":78,\"fx\":\"东南风\","
  144. "\"fl\":\"2级\","
  145. "\"type\":\"晴\",\"notice\":"
  146. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"23\",\"high\":\"高温 33℃\",\"low\":\"低温 "
  147. "23℃\",\"ymd\":\"2023-08-23\",\"week\":\"星期三\",\"sunrise\":\"05:52\",\"sunset\":\"19:04\",\"aqi\":71,\"fx\":\"南风\","
  148. "\"fl\":\"2级\","
  149. "\"type\":\"中雨\",\"notice\":"
  150. "\"记得随身携带雨伞哦\"},{\"date\":\"24\",\"high\":\"高温 31℃\",\"low\":\"低温 "
  151. "21℃\",\"ymd\":\"2023-08-24\",\"week\":\"星期四\",\"sunrise\":\"05:52\",\"sunset\":\"19:03\",\"aqi\":74,\"fx\":\"东风\","
  152. "\"fl\":\"2级\","
  153. "\"type\":\"晴\",\"notice\":"
  154. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"25\",\"high\":\"高温 30℃\",\"low\":\"低温 "
  155. "23℃\",\"ymd\":\"2023-08-25\",\"week\":\"星期五\",\"sunrise\":\"05:53\",\"sunset\":\"19:02\",\"aqi\":93,\"fx\":\"东风\","
  156. "\"fl\":\"1级\","
  157. "\"type\":\"小雨\",\"notice\":"
  158. "\"雨虽小,注意保暖别感冒\"},{\"date\":\"26\",\"high\":\"高温 25℃\",\"low\":\"低温 "
  159. "22℃\",\"ymd\":\"2023-08-26\",\"week\":\"星期六\",\"sunrise\":\"05:54\",\"sunset\":\"19:00\",\"aqi\":80,\"fx\":\"东北风\","
  160. "\"fl\":\"1级\","
  161. "\"type\":\"阴\",\"notice\":"
  162. "\"不要被阴云遮挡住好心情\"},{\"date\":\"27\",\"high\":\"高温 27℃\",\"low\":\"低温 "
  163. "20℃\",\"ymd\":\"2023-08-27\",\"week\":\"星期日\",\"sunrise\":\"05:55\",\"sunset\":\"18:59\",\"aqi\":74,\"fx\":\"西北风\","
  164. "\"fl\":\"1级\","
  165. "\"type\":\"阴\",\"notice\":"
  166. "\"不要被阴云遮挡住好心情\"},{\"date\":\"28\",\"high\":\"高温 30℃\",\"low\":\"低温 "
  167. "20℃\",\"ymd\":\"2023-08-28\",\"week\":\"星期 "
  168. "一\",\"sunrise\":\"05:55\",\"sunset\":\"18:58\",\"aqi\":80,\"fx\":\"东北风\",\"fl\":\"2级\",\"type\":\"多云\",\"notice\":"
  169. "\"阴晴之间,谨防紫外线侵扰\"},{\"date\":\"29\",\"high\":"
  170. "\"高温 30℃\",\"low\":\"低温 "
  171. "20℃\",\"ymd\":\"2023-08-29\",\"week\":\"星期二\",\"sunrise\":\"05:56\",\"sunset\":\"18:56\",\"aqi\":80,\"fx\":\"东北风\","
  172. "\"fl\":\"2级\","
  173. "\"type\":\"多云\",\"notice\":"
  174. "\"阴晴之间,谨防紫外线侵扰\"},{\"date\":\"30\",\"high\":\"高温 31℃\",\"low\":\"低温 "
  175. "20℃\",\"ymd\":\"2023-08-30\",\"week\":\"星期三\",\"sunrise\":\"05:57\",\"sunset\":\"18:55\",\"aqi\":92,\"fx\":\"南风\","
  176. "\"fl\":\"1级\","
  177. "\"type\":\"晴\",\"notice\":"
  178. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"31\",\"high\":\"高温 33℃\",\"low\":\" 低温 "
  179. "22℃\",\"ymd\":\"2023-08-31\",\"week\":\"星期四\",\"sunrise\":\"05:57\",\"sunset\":\"18:54\",\"aqi\":91,\"fx\":\"南风\","
  180. "\"fl\":\"1级\","
  181. "\"type\":\"晴\",\"notice\":"
  182. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"01\",\"high\":\"高温 34℃\",\"low\":\"低温 "
  183. "23℃\",\"ymd\":\"2023-09-01\",\"week\":\"星期五\",\"sunrise\":\"05:58\",\"sunset\":\"18:52\",\"aqi\":91,\"fx\":\"西风\","
  184. "\"fl\":\"1级\","
  185. "\"type\":\"晴\",\"notice\":"
  186. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"02\",\"high\":\"高温 36℃\",\"low\":\"低温 "
  187. "25℃\",\"ymd\":\"2023-09-02\",\"week\":\"星期六\",\"sunrise\":\"05:59\",\"sunset\":\"18:51\",\"aqi\":78,\"fx\":\"南风\","
  188. "\"fl\":\"1级\","
  189. "\"type\":\"阴\",\"notice\":"
  190. "\"不要被阴云遮挡住好心情\"},{\"date\":\"03\",\"high\":\"高温 35℃\",\"low\":\"低温 "
  191. "24℃\",\"ymd\":\"2023-09-03\",\"week\":\"星期日\",\"sunrise\":\"06:00\",\"sunset\":\"18:50\",\"aqi\":82,\"fx\":\"东北风\","
  192. "\"fl\":\"1级\","
  193. "\"type\":\"晴\",\"notice\":"
  194. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"04\",\"high\":\"高温 35℃\",\"low\":\"低温 "
  195. "25℃\",\"ymd\":\"2023-09-04\",\"week\":\"星期一\",\"sunrise\":\"06:00\",\"sunset\":\"18:48\",\"aqi\":88,\"fx\":\"南风\","
  196. "\"fl\":\"2级\","
  197. "\"type\":\"晴\",\"notice\":"
  198. "\"愿你拥有比阳光明媚的心情\"},{\"date\":\"05\",\"high\":\"高温 35℃\",\"low\":\"低温 "
  199. "25℃\",\"ymd\":\"2023-09-05\",\"week\":\"星期二\",\"sunrise\":\"06:01\",\"sunset\":\"18:47\",\"aqi\":58,\"fx\":\"南风\","
  200. "\"fl\":\"2级\","
  201. "\"type\":\"阴\",\"notice\":"
  202. "\"不要被阴云遮挡住好心情\"}],\"yesterday\":{\"date\":\"21\",\"high\":\"高温 34℃\",\"low\":\"低温 "
  203. "24℃\",\"ymd\":\"2023-08-21\",\"week\":\" "
  204. "星期一\",\"sunrise\":\"05:50\",\"sunset\":\"19:07\",\"aqi\":60,\"fx\":\"西风\",\"fl\":\"2级\",\"type\":\"小雨\","
  205. "\"notice\":"
  206. "\"雨虽小,注意保暖别感冒\"}}}";
  207. return printfJsonCompare(jsonstr);
  208. }
  209. static RyanJsonBool_e testArrayJsonMemory(void)
  210. {
  211. char *jsonstr =
  212. "{\"item1\":{\"arrayInt\":[16,16,16,16,16,16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89,16.89,16.89,16."
  213. "89,16.89,16.89],"
  214. "\"arrayString\":[\"hello\",\"hello\","
  215. "\"hello\",\"hello\",\"hello\",\"hello\",\"hello\",\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,"
  216. "false,null,16,16.89,"
  217. "\"hello\",true,false,null]},\"item2\":{"
  218. "\"arrayInt\":[16,16,16,16,16,16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89,16."
  219. "89],\"arrayString\":["
  220. "\"hello\",\"hello\",\"hello\",\"hello\","
  221. "\"hello\",\"hello\",\"hello\",\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null,16,16.89,"
  222. "\"hello\",true,false,"
  223. "null]},\"item3\":{\"arrayInt\":[16,16,16,"
  224. "16,16,16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89],\"arrayString\":["
  225. "\"hello\",\"hello\","
  226. "\"hello\",\"hello\",\"hello\",\"hello\","
  227. "\"hello\",\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null,16,16.89,\"hello\",true,false,"
  228. "null]},\"item4\":{"
  229. "\"arrayInt\":[16,16,16,16,16,16,16,16,16,16],"
  230. "\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89,16.89],\"arrayString\":[\"hello\",\"hello\","
  231. "\"hello\",\"hello\","
  232. "\"hello\",\"hello\",\"hello\",\"hello\","
  233. "\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null,16,16.89,\"hello\",true,false,null]}}";
  234. return printfJsonCompare(jsonstr);
  235. }
  236. static RyanJsonBool_e testSmallMixedJsonMemory(void)
  237. {
  238. char *jsonstr = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}";
  239. return printfJsonCompare(jsonstr);
  240. }
  241. static RyanJsonBool_e testSmallStringJsonMemory(void)
  242. {
  243. char *jsonstr =
  244. "{\"inter\":\"16\",\"double\":\"16.89\",\"string\":\"hello\",\"boolTrue\":\"true\",\"boolFalse\":\"false\",\"null\":"
  245. "\"null\"}";
  246. return printfJsonCompare(jsonstr);
  247. }
  248. static RyanJsonBool_e testCompressedBusinessJsonMemory(void)
  249. {
  250. char *jsonstr =
  251. "{\"0\":\"0\",\"1\":\"189774523\",\"2\":{\"7\":\"3\",\"8\":\"103\",\"9\":\"37\",\"20\":\"0\",\"26\":\"37\",\"27\":"
  252. "\"367\",\"28\":\"367\",\"s\":\"0\",\"t\":\"0\",\"a\":\"24.98\",\"2a\":\"0\",\"1p\":\"23628\"},\"3\":\"0\",\"22\":"
  253. "\"epmgrow1105\",\"23\":\"0\",\"29\":\"0\",\"i\":\"4\",\"b\":\"900\",\"c\":\"1\",\"rsrp\":\"-111\",\"rsrq\":\"-4\","
  254. "\"sinr\":\"0\",\"soc\":\"XXXXXXX\",\"j\":\"0\",\"g\":\"898604asdf0210\",\"h\":\"866968798839\",\"d\":\"1.3.5."
  255. "00.20991231\",\"f\":\"0\",\"k\":\"1\",\"l\":\"20000\",\"m\":\"20000\",\"u\":\"0\",\"v\":\"0\",\"e\":\"1\",\"w\":\"0."
  256. "00\",\"n\":\"0\",\"2h\":\"0\",\"o\":\"30\",\"1v\":\"12000\",\"2c\":\"0\",\"p\":\"1\",\"q\":\"1\",\"x\":\"0\",\"y\":"
  257. "\"167\",\"r\":\"0\",\"1x\":\"0\",\"1w\":\"0\",\"1y\":\"100.00\",\"1u\":\"0\"}";
  258. printfJsonCompare(jsonstr);
  259. return RyanJsonTrue;
  260. }
  261. RyanJsonBool_e RyanJsonMemoryFootprintTest(void)
  262. {
  263. int32_t result = 0;
  264. uint32_t testRunCount = 0;
  265. uint64_t funcStartMs;
  266. runTestWithLogAndTimer(testMixedJsonMemory);
  267. runTestWithLogAndTimer(testObjectJsonMemory);
  268. runTestWithLogAndTimer(testArrayJsonMemory);
  269. runTestWithLogAndTimer(testSmallMixedJsonMemory);
  270. runTestWithLogAndTimer(testSmallStringJsonMemory);
  271. runTestWithLogAndTimer(testCompressedBusinessJsonMemory);
  272. return RyanJsonTrue;
  273. }