文件读写性能的一些测试总结

背景

最近替换了项目内部的 log 库,使用 spdlog 开源库:

github 地址: https://github.com/gabime/spdlog

spdlog 在主页中所提及到其性能达: 5,777,626/sec ,惊为天人

因此认真阅读了 spdlog 源码,做了些实验,摸底了下文件读写性能

fwrite 函数

用户态函数,作用:把文件数据从写到用户态缓冲区

缓冲区可以通过 setbuf/setvbuf/setbuffer 来指定(可自己控制其大小),或 libc 内置缓冲区(对程序不可见)

来写个测试程序,测试下其性能:

#include <chrono>
#include <cstdio>
#include <cstdlib>

void test1(int _)
{
	printf("TEST CASE: 只调用 fwrite\n");
	FILE* f = fopen("test.txt", "wb");
	if (!f)
	{
		printf("can not open file\n");
		exit(1);
	}

	int iters = 1000000;
	using std::chrono::high_resolution_clock;
	auto start = high_resolution_clock::now();
	for (int i = 0; i < iters; i++)
	{
		char msg[1024];
		auto len = snprintf(msg, sizeof(msg), "Hello logger: msg number %d\n", i);
		fwrite(msg, len, 1, f);
	}
	auto delta = high_resolution_clock::now() - start;
	auto delta_d = std::chrono::duration_cast<std::chrono::duration<double>>(delta).count();
	printf("Elapsed: %0.2f secs %d/sec\n", delta_d, int(iters / delta_d));
	fclose(f);
}

测试结果如下:
在这里插入图片描述
TPS 在 600w+/s

(如果想要确保上述测试无调用 fflush ,可以通过 setbuf/setvbuf/setbuffer 把缓冲区设置大些)

fflush 函数

system call 函数,会切一次用户态到内核态,作用: 把文件数据从用户态缓存区到内核态 page cache 页中

来写个测试程序,测试下其性能:

#include <chrono>
#include <cstdio>
#include <cstdlib>

void test2(int _)
{
	printf("TEST CASE: 每次调用 fwrite fflush\n");
	FILE* f = fopen("test.txt", "wb");
	if (!f)
	{
		printf("can not open file\n");
		exit(1);
	}

	int iters = 1000000;
	using std::chrono::high_resolution_clock;
	auto start = high_resolution_clock::now();
	for (int i = 0; i < iters; i++)
	{
		char msg[1024];
		auto len = snprintf(msg, sizeof(msg), "Hello logger: msg number %d\n", i);
		fwrite(msg, len, 1, f);
		fflush(f);
	}
	auto delta = high_resolution_clock::now() - start;
	auto delta_d = std::chrono::duration_cast<std::chrono::duration<double>>(delta).count();
	printf("Elapsed: %0.2f secs %d/sec\n", delta_d, int(iters / delta_d));
	fclose(f);
}

测试结果如下:
在这里插入图片描述
TPS 在 70w+/s

spdlog 提供的性能测试分析

spdlog 提供的性能测试 TPS 在 500w+/sec ,因此可以断定该基准测试没有调用过 fflush

本人 review 了下其测试代码: https://github.com/gabime/spdlog/blob/v1.x/bench/bench.cpp

确实无调用 fflush

并提 issue ,向作者确认: https://github.com/gabime/spdlog/issues/1392

作者的回复也明确说明无调用 fflush :

This is typical and recommended usage. you Of course calling flush on each call would hurt performance and you are welcome to perform your own bench according to your needs.

因此, spdlog 对外号称的 Very fast, header-only/compiled, C++ logging library. 是有些沽名钓誉,混淆视听的

注:本文没有诋毁 spdlog 的意思, spdlog 非常好用与扩展,后续会写下其源代码分析

内核 page cache 页

fflush 后数据到 page cache 页了,有没有感性的认识呢?

是有的,请看下面的测试:
在这里插入图片描述
内核维护 page cache 页游自己的算法,程序通常是无法干预的,也不需要干预

一次压测遇到的容器内存占用满问题

监视容器的工具,内存计算包含了 buff/cache 字段值。

宿主机内存 150G+ ,而容器内存 8G

由于压测,服务在大量的写文件,导致 buff/cache 值很高

于是监测图形上内存都是 100% 被占满

该问题,前面合作方追问一直无法给予正面解释,现在终于弄明白啦!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fananchong2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值