将yyjson的默认内存分配器替换为mimalloc

最近发现一个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

 

上一篇:用于访问播客文件的Rhythmbox插件无法看到它们


下一篇:Android播客