C++基于多设计模式下的同步异步日志系统day7(终)

C++基于多设计模式下的同步&异步日志系统day7(终)

📟作者主页:慢热的陕西人

🌴专栏链接:C++基于多设计模式下的同步&异步日志系统

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

主要内容对项目的目录结构进行了梳理,以及测试了代码的性能,分别在云服务器和本地的虚拟机上进行了测试

在这里插入图片描述

文章目录

  • C++基于多设计模式下的同步&异步日志系统day7(终)
    • 1.项目目录结构梳理
    • 2.项目性能测试代码的设计和实现
      • 2.1测试工具的编写
      • 2.2测试
        • ①云服务器环境下:
        • ②本地虚拟机:

1.项目目录结构梳理

  • Example

    用于存储我们的样例代码文件

  • Extend

    存储我们的拓展代码文件

  • Logs

    存储项目的所有的头文件

  • PreSturdy

    项目前期需要补充学习的代码内容文件

image-20240305180006504

2.项目性能测试代码的设计和实现

测试三要素:①测试环境②测试方法③测试结果

2.1测试工具的编写

①可以控制写日志线程数量

②可以控制写日志的总数量

③分别对同步/异步日志器,进行性能测试

  • 需要测试单写日志线程的性能
  • 需要测试多写日志线程的性能

实现

  • 封装一个接口,传入日志器名称,以及线程数量,以及日志数量,单条日志大小
  • 在接口内,创建指定数量的线程,各自负责一部分日志的输出
  • 在输出之前开始计时,在输出结束之后计时结束,所耗时间 = 结束时间 - 起始时间
  • 每秒输出量 = 总日志数 / 总时间
  • 每秒输出大小 = 日志数量 * 单个日志大小 / 总耗时

注意:异步日志输出这里,我们采用非安全模式,纯内存写入(不考虑实际落地的时间)

#include"../Logs/xupt.h"#include<vector>
#include<thread>
#include<chrono>void bench(const std::string& logger_name, size_t thread_count, size_t msg_count, size_t msg_len)
{//1.获取日志器xupt::Logger::ptr logger = xupt::getLogger(logger_name);if(logger.get() == nullptr)  //获取日志器失败{return ;}std::cout << "测试日志:" << msg_count << "条, 总大小:" << msg_count * msg_len / 1024 <<"kb" << std::endl;//2.组织指定长度的日志消息std::string msg(msg_len - 1, 'A');  //这里长度减一是为了后续占用一个换行符//3.创建指定数量的线程std::vector<std::thread> threads;int msg_per_thr = msg_count / thread_count;std::vector<double> cost_arry(thread_count);  //存储每个线程消耗的时间for(size_t i = 0; i < thread_count; ++i){threads.emplace_back([&, i](){//4.线程函数内部开始计时auto start = std::chrono::high_resolution_clock::now();//5.开始循环写日志for(int j = 0; j < msg_per_thr; ++j){logger->fatal("%s", msg.c_str());}//6.线程函数内部结束计时auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> cost = end - start;cost_arry[i] = cost.count(); //将每次的线程耗时存储在数组中,以备计算总耗时std::cout <<"\t线程" << i << ": " << "\t 输出数量" << msg_per_thr << ", 耗时" << cost.count() << "s" << std::endl;});}for(int i = 0; i < thread_count; ++i){threads[i].join();}//7.计算总耗时double max_cost = cost_arry[0];for(int i = 0; i < thread_count; ++i) max_cost = max_cost < cost_arry[i] ? cost_arry[i] : max_cost;size_t msg_per_sec = msg_count / max_cost; //每秒输出的日志消息数量size_t size_per_sec = (msg_per_sec * msg_len) / (max_cost * 1024);//每秒输出的kb数//8.进行输出打印std::cout << "\t总耗时:" << max_cost << "s" << std::endl;std::cout << "\t每秒输出的日志消息数量:" << msg_per_sec << std::endl;std::cout << "\t每秒输出的日志大小:" << size_per_sec << "kb"<<std::endl;
}void sync_bench()
{std::unique_ptr<xupt::LoggerBuilder> builder(new xupt::GlobalLoggerBuilder());builder->buildLoggerName("sync_logger");builder->buildLoggerType(xupt::LoggerType::LOGGER_SYNC);builder->buildFomatter("%m%n");builder->buildSink<xupt::FileSink>("./logfile/sync.log");builder->build();    bench("sync_logger", 3, 1000000, 100);
}void async_bench()
{std::unique_ptr<xupt::LoggerBuilder> builder(new xupt::GlobalLoggerBuilder());builder->buildLoggerName("async_logger");builder->buildLoggerType(xupt::LoggerType::LOGGER_ASYNC);builder->buildFomatter("%m%n");builder->buildEnableUnsafeAsync(); //开启非安全模式---为了将实际落地时间排除在外builder->buildSink<xupt::FileSink>("./logfile/async.log");builder->build();    bench("async_logger", 5, 1000000, 100);
}int main()
{//sync_bench();async_bench();return 0;
}

2.2测试

我们分别在云服务器和本地的虚拟器上进行测试,分别测试同步单线程,同步多线程,异步单线程,异步多线程

云服务器环境:

  • CPU:2核
  • 内存:2GB

本地虚拟机环境:

  • CPU:AMDRyzen5 5600H withRadeonGraphics3.30GHz
  • RAM:16GDDR4 3200
  • ROM:512G-SSD
  • OS:CentOS7虚拟机(4CPU核⼼/2G内存)
①云服务器环境下:

在这里插入图片描述

②本地虚拟机:

image-20240305222437795

我们可以看出本地虚拟机的同步单线程的优势比云服务器的同步单线程优势大很多,那么证明本地的虚拟机串行执行的速度相对较快

但是我们观察的到同步不管是多线程还是单线程虚拟机都是比云服务器强很多的,但是异步不管是多线程还是单线程都比云服务器慢一些。

因为异步的方式是不包含将日志写入到磁盘中的时间,那么证明本地的虚拟机IO的速度比云服务器的IO速度要快不少。

到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/269555.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美易官方《盘前:美国股指期货温和走低》

美国股指期货在盘前交易中温和走低&#xff0c;市场情绪在美联储主席鲍威尔即将作证前显得谨慎。投资者对即将公布的证词内容充满期待&#xff0c;以寻求对美联储未来货币政策的更多线索。 鲍威尔即将在国会作证&#xff0c;这是市场关注的焦点事件之一。他的证词可能会对美元汇…

字节同事问我:我的Postman为什么连不了数据库?

postman本身没有数据库连接功能&#xff0c;所以用到了node.js中的xmysql实现Rest API的生成&#xff0c;利用postman进行请求&#xff0c;获取需要的数据&#xff0c;来做数据准备或断言。 1 安装 安装node.js&#xff1a;要求版本大于等于7.6 首先保证你的环境上有node.js…

【NR 定位】3GPP NR Positioning 5G定位标准解读(四)

目录 前言 6 Signalling protocols and interfaces 6.1 支持定位操作的网络接口 6.1.1 通用LCS控制平面架构 6.1.2 NR-Uu接口 6.1.3 LTE-Uu接口 6.1.4 NG-C接口 6.1.5 NL1接口 6.1.6 F1接口 6.1.7 NR PC5接口 6.2 终端协议 6.2.1 LTE定位协议&#xff08;LPP&#x…

贪心算法(区间问题)

452. 用最少数量的箭引爆气球 题目(求无重复区间) 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可以沿着…

爬虫入门到精通_实战篇11(使用代理处理反爬抓取微信文章)_PyQuery使用

1 目标 搜狗-微信这个网址来爬取微信的文章&#xff1a; ps&#xff1a;登录后才能查看第10页之后的内容&#xff1a; 量翻页触发了网站的反爬虫措施&#xff0c;导致ip被封&#xff0c;需要进行解锁。 然而从doc中可以看到&#xff0c;请求失败的那页&#xff08;状态码应…

【力扣白嫖日记】1045.买下所有产品的客户

前言 练习sql语句&#xff0c;所有题目来自于力扣&#xff08;https://leetcode.cn/problemset/database/&#xff09;的免费数据库练习题。 今日题目&#xff1a; 1045.买下所有产品的客户 表&#xff1a;Customer 列名类型customer_idintproduct_keyint 该表可能包含重复…

【Vue3】深入理解Vue中的ref属性

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

MyCAT集群——MyCAT2如何配置读写分离

先搭载MySQL一主两从 192.168.20.110MyCAT192.168.20.111Master192.168.20.112slave1192.168.20.113slave2 配置就不写了&#xff0c;比较基础&#xff0c;写一下步骤 1.进入mysql配置文件或者其子配置文件&#xff0c;添加server_id,开启gtidgtid_modeON,enforce-gtid-cons…

个人社区 项目测试

目 录 一.背景及介绍二.功能详情三.手动测试1.编写测试用例2.测试 一.背景及介绍 该项目采用了前后端分离技术&#xff0c;把我们的数据保存到数据库中&#xff0c;操作对象是用户和个人文章编辑保存&#xff0c;前端的页面实现了登录&#xff0c;列表&#xff0c;编辑&#x…

学习JAVA的第十三天(基础)

目录 API之Arrays 将数组变成字符串 二分查找法查找元素 拷贝数组 填充数组 排序数组 Lambda表达式 集合的进阶 单列集合 体系结构 Collection API之Arrays 操作数组的工具类 将数组变成字符串 //将数组变成字符串char[] arr {a,b,c,d,e};System.out.println(Arra…

leetcode--接雨水(双指针法,动态规划,单调栈)

目录 方法一&#xff1a;双指针法 方法二&#xff1a;动态规划 方法三&#xff1a;单调栈 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 黑色的是柱子&#xff0c;蓝色的是雨水&#xff0c;我们先来观察一下雨水的分布情况: 雨水落在凹槽之间&#xff0c;在一个凹槽的…

第十三届蓝桥杯嵌入式省赛程序设计详细题解

第十三届蓝桥杯嵌入式省赛题目相对于第十二届较为简单&#xff0c;没有那么多串口的数据处理以及判断&#xff01; 第十三届省赛主要是制作一个可由串口设置密码的密码锁。本实验中&#xff0c;我们将用到LED模块、按键模块、串口模块、定时器的PWM模块以及官方会提供源码的LC…

01、MongoDB -- 下载、安装、配置文件等配置 及 副本集配置

目录 MongoDB -- 下载、安装、配置 及 副本集配置启动命令启动 mongodb 的服务器&#xff08;单机和副本集&#xff09;启动单机模式的 mongodb 服务器启动副本集的 3 个副本节点&#xff08;mongodb 服务器&#xff09; 启动 mongodb 的客户端 MongoDB 下载MongoDB 安装1、解压…

UE5 UE4 不同关卡使用Sequence动画

参考自&#xff1a;关于Datasmith导入流程 | 虚幻引擎文档 (unrealengine.com) 关卡中的Sequence动画序列&#xff0c;包含特定关卡中的Actor的引用。 将同一个Sequcen动画资源放入其他关卡&#xff0c;Sequence无法在新关卡中找到相同的Actor&#xff0c;导致报错。 Sequen…

android Service 与 activity 通信 并不断传数据

注&#xff1a;这只是个Demo 以下载为案例&#xff0c;实现开启下载&#xff0c;暂停下载&#xff0c;下载进度不断发送给activity class DownloadService : Service() {override fun onBind(intent: Intent?): IBinder? {return MyBinder()}inner class MyBinder : Binder…

Java知识点总结(二)

ID生成策略 主键自增id 主键自动增长&#xff0c;不用手工设值、数字型&#xff0c;占用空间小、检索非常有利、有顺序&#xff0c;不会重复&#xff0c;但在迁移旧数据是会出现id冲突 UUID 基于时间&#xff0c;计数器和地址生成32位的id redis生成id 原子性自增&#xff0c;并…

Flask入门一(介绍、Flask安装、Flask运行方式及使用、虚拟环境、调试模式、配置文件、路由系统)

文章目录 一、Flask介绍二、Flask创建和运行1.安装2.快速使用3.Flask小知识4.flask的运行方式 三、Werkzeug介绍四、Jinja2介绍五、Click CLI 介绍六、Flask安装介绍watchdog使用python--dotenv使用&#xff08;操作环境变量&#xff09; 七、虚拟环境介绍Mac/linux创建虚拟环境…

Android Gradle开发与应用 (三) : Groovy语法概念与闭包

1. Groovy介绍 Groovy是一种基于Java平台的动态编程语言&#xff0c;与Java是完全兼容&#xff0c;除此之外有很多的语法糖来方便我们开发。Groovy代码能够直接运行在Java虚拟机&#xff08;JVM&#xff09;上&#xff0c;也可以被编译成Java字节码文件。 以下是Groovy的一些…

2024.02.29作业

1. TCP模型 server #include "test.h"#define SER_IP "192.168.191.128" #define SER_PORT 9999int main(int argc, char const *argv[]) {int sfd -1;sfd socket(AF_INET, SOCK_STREAM, 0);if (-1 sfd){perror("socket error");return -1;…

Java生成 word报告

Java生成 word报告 一、方案比较二、Apache POI 生成三、FreeMarker 生成 在网上找了好多天将数据库信息导出到 word 中的解决方案&#xff0c;现在将这几天的总结分享一下。总的来说&#xff0c;Java 导出 word 大致有 5 种。 一、方案比较 1. Jacob Jacob 是 Java-COM Bri…