最近发现一个C++的json解析库yyjson,刚好未来也可能有这方面的需求,所以就试用了一下。简单易用,效果也不错。但是看了源码发现内存分配使用的是系统默认的stdlib.h,所以就想替换为mimalloc,看看效果如何。
为了尽量兼容之前的代码,所以mimalloc选择使用mimalloc-override.h,已经把mimalloc的函数替换为了stdlib.h的函数,一般使用的话,直接把stdlib.h替换为mimalloc-override.h即可。但是yyjson这个项目不可以,还得稍作改动。
第一步,修改yyjson.h头文件
//#include <stdlib.h> // 注释掉这行
#include <stddef.h>
#include <limits.h>
#include <string.h>
#include <float.h>
...
typedef struct yyjson_alc {
/* Same as libc's malloc(), should not be NULL. */
/* void *(*malloc)(void *ctx, size_t size); 此行替换为以下代码 */
void *(*yyjson_malloc)(void *ctx, size_t size);
/* Same as libc's realloc(), should not be NULL. */
/* void *(*realloc)(void *ctx, void *ptr, size_t size); 此行替换为以下代码 */
void *(*yyjson_realloc)(void *ctx, void *ptr, size_t size);
/* Same as libc's free(), should not be NULL. */
/* void (*free)(void *ctx, void *ptr); 此行替换为以下代码*/
void (*yyjson_free)(void *ctx, void *ptr);
/* A context for allocator, can be NULL. */
void *ctx;
} yyjson_alc;
第二步,替换相关代码
在yyjson.h和yyjson.c文件中
将所有alc.realloc替换为alc.yyjson_realloc
将所有alc.malloc替换为alc.yyjson_malloc
将所有alc.free替换为alc.yyjson_free
将所有alc->realloc替换为alc->yyjson_realloc
将所有alc->malloc替换为alc->yyjson_malloc
将所有alc->free替换为alc->yyjson_free
第三步,修改yyjson.c代码
在文件头部添加
#include <mimalloc-override.h>
将mimalloc的相关库引用之后,替换工作完成。
测试
测试代码
int main()
{
const char* json = "{\"name\":\"Mash\",\"star\":4,\"hits\":[2,2,1,3]}";
boost::progress_timer t; // 也可以使用其他计时器,本人用的boost库
for (int i = 0; i < 100 * 10000; i++)
{
yyjson_doc* doc = yyjson_read(json, strlen(json), 0);
yyjson_val* root = yyjson_doc_get_root(doc);
yyjson_val* name = yyjson_obj_get(root, "name");
//printf("name: %s\n", yyjson_get_str(name));
//printf("name length:%d\n", (int)yyjson_get_len(name));
yyjson_val* star = yyjson_obj_get(root, "star");
//printf("star: %d\n", (int)yyjson_get_int(star));
yyjson_val* hits = yyjson_obj_get(root, "hits");
size_t idx, max;
yyjson_val* hit;
yyjson_arr_foreach(hits, idx, max, hit) {
//printf("hit%d: %d\n", (int)idx, (int)yyjson_get_int(hit));
}
yyjson_doc_free(doc);
}
std::cout << "总共运行:" << t.elapsed() << " 秒\n";
}
然后分别引用stdlib.h和mimalloc-override.h跑了一下,结果如下:
数据量 | stdlib.h | mimalloc-override.h | 模式 |
100万 | 6.415 秒 | 42.221 秒 | Debug |
不得不说,看到这个结果我震精了,使用了mimalloc后非但没快,更慢了,还慢的如此令人发指。稍微思索了一下,估计是Debug模式的锅,那就换用Release模式试一下吧。
数据量 | stdlib.h | mimalloc-override.h | 模式 |
100万 | 1.32 | 1.05 | Release |
100万 | 0.448 | 0.223 | Release(开优化) |
果然速度上来了,为了避免Debug模式下感人的速度,再稍稍把代码修改一下,打开yyjson.c文件把之前的
#include <mimalloc-override.h>
替换为:
#ifdef _DEBUG
#include <stdlib.h>
#else
#include <mimalloc-override.h>
#endif