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速度要快不少。

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CAN总线位时序的介绍

CAN控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平&#xff0c;二者必居其一。发送方通过使总线电平发生变化&#xff0c;将消息发送给接收方。 显性电平对应逻辑 0&#xff0c;CAN_H 和 CAN_L 之差为 2.5V 左右。而隐性电平对应逻辑 1&#xff0c…

深入理解现代JavaScript:从语言特性到应用实践

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 JavaScript作为一门动态、解释性脚本语言&…

前端面试题 ===> 【JavaScript - 高级】

公众号&#xff1a;需要以下pdf&#xff0c;关注下方 2023已经过完了&#xff0c;让我们来把今年的面试题统计号&#xff0c;来备战今年的金三银四&#xff01;所以&#xff0c;不管你是社招还是校招&#xff0c;下面这份前端面试工程师高频面试题&#xff0c;请收好。 JavaScr…

步进电机驱动器接法

实物 参数 共阳极&#xff1a; 使能给高电平有效 共阴极&#xff1a; 使能给低电平有效 整体接线 参考内容 B站UP范辉

基于Java SSM springboot+VUE+redis实现的前后端分类版网上商城项目

基于Java SSM springbootVUEredis实现的前后端分类版网上商城项目 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐…

深入理解Lambda表达式:基础概念与实战演练【第114篇—python:Lambda表达式】

深入理解Lambda表达式&#xff1a;基础概念与实战演练 在现代编程语言中&#xff0c;Lambda表达式作为一种轻量级的匿名函数形式&#xff0c;越来越受到程序员的青睐。特别是在函数式编程兴起的今天&#xff0c;Lambda表达式在简化代码、提高可读性方面发挥着重要作用。本文将…

【Web】浅浅地聊JDBC java.sql.Driver的SPI后门

目录 SPI定义 SPI核心方法和类 最简单的SPIdemo演示 回顾JCBC基本流程 为什么JDBC要有SPI JDBC java.sql.Driver后门利用与验证 SPI定义 SPI&#xff1a; Service Provider Interface 官方定义&#xff1a; 直译过来是服务提供者接口&#xff0c;学名为服务发现机制 它通…

加油站“变身”快充站,探讨充电新模式

摘要&#xff1a;新能源汽车规模化发展的同时&#xff0c;充电不便利的痛点愈发明显。在未来的新能源汽车行业发展当中&#xff0c;充电的矛盾要远远大于造车的矛盾&#xff0c;解决好充电的问题成为电动汽车行业发展的一个突出问题。解决充电补能问题&#xff0c;重要的方式之…

【牛客】VL60 使用握手信号实现跨时钟域数据传输

题目描述 分别编写一个数据发送模块和一个数据接收模块&#xff0c;模块的时钟信号分别为clk_a&#xff0c;clk_b。两个时钟的频率不相同。数据发送模块循环发送0-7&#xff0c;在每个数据传输完成之后&#xff0c;间隔5个时钟&#xff0c;发送下一个数据。请在两个模块之间添加…

(vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)

(vue)el-checkbox 实现展示区分 label 和 value&#xff08;展示值与选中获取值需不同&#xff09; 后端数据 解决方法 在 el-checkbox 标签中间传入要展示的文本即可&#xff0c;代码如下&#xff1a; <el-checkbox-groupv-model"formInline.processFieldList"…

【C语言】指针超级无敌金刚霹雳进阶(但不难,还是基础)

点击这里访问我的博客主页~~ 对指针概念还不太清楚的点击这里访问上一篇指针初阶2.0 上上篇指针初阶1.0 谢谢各位大佬的支持咯 今天我们一起来学习指针进阶内容 指针进阶 一、指针变量1、字符指针变量2、数组指针变量①数组指针变量的定义②数组指针变量的初始化 3、函数指…

代码随想录第50天|● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

文章目录 ● 123.买卖股票的最佳时机III思路代码一&#xff1a;dp二维数组代码二&#xff1a;四个数存储 ● 188.买卖股票的最佳时机IV思路&#xff1a;代码&#xff1a; ● 123.买卖股票的最佳时机III 思路 dp[i][j]中 i表示第i天&#xff0c;j为 [0 - 4] 五个状态&#xff0…

C++ string类详解及模拟实现

目录 【本节目标】 1. 为什么学习string类&#xff1f; 1.1 C语言中的字符串 1.2 面试题(暂不做讲解) 2. 标准库中的string类 2.1 string类(了解) 2.2 string类的常用接口说明&#xff08;注意下面我只讲解最常用的接口&#xff09; 3. string类的模拟实现 3.1string类常用…

操作系统篇——虚拟内存到底是个啥?

先祝大家春招都过&#xff0c;后台私信我&#xff0c;可免费获得面试宝典&#xff0c;祝大家都和我一样&#xff0c;顺顺利利面大厂!!! 为什么不直接使用物理内存 虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存&#xff08;一个连续完整的…

YOLOv9推理详解及部署实现

目录 前言零、YOLOv9简介一、YOLOv9推理(Python)1. YOLOv9预测2. YOLOv9预处理3. YOLOv9后处理4. YOLOv9推理 二、YOLOv9推理(C)1. ONNX导出2. YOLOv9预处理3. YOLOv9后处理4. YOLOv9推理 三、YOLOv9部署1. 源码下载2. 环境配置2.1 配置CMakeLists.txt2.2 配置Makefile 3. ONNX…

useState多次渲染页面卡顿 useMemo

useState多次渲染页面卡顿 state变化了组件自然应该重新进行渲染&#xff0c;但有时我们并不需要。 React.memo()(useMemo)是一个高阶组件&#xff0c;它接收另一个组件作为参数&#xff0c;并且会返回一个包装过的新组件&#xff0c;包装过的新组件就会具有缓存作用&#xff…

已经连接过github远程库,如何再次推送及删除远程库的内容

基于上次将文件推送到已经建好的github远程库上&#xff0c;此篇文章主要介绍如何再次推送文件去直接已经连接过的远程库&#xff0c;以此如何删除远程库中不想要的文件。 一、推送文件到远程库 1.将所需推送的文件拉入本地库所建的文件夹下&#xff1a;{ex&#xff1a;JVM相…

HTML5:七天学会基础动画网页8

2D缩放:scale scale(x,y) 2D缩放转换&#xff0c;改变元素的宽度和 高度&#xff0c;值为缩放的倍数。 scaleX(n) 2D缩放转换&#xff0c;改变元素的宽度。 scaleY(n) 2D播放转换&#xff0c;改变元素的高度。 跟前面提到的平移同理&#xff0…

Redis 7.0版本主从复制机制

1、引言 Redis是一个开源、高性能、内存键值存储系统&#xff0c;同时也提供了数据结构服务器的功能。它支持五种主要的数据类型&#xff1a;字符串&#xff08;String&#xff09;、哈希表&#xff08;Hashes&#xff09;、列表&#xff08;Lists&#xff09;、集合&#xff…

Vue基础篇

Vue Vue是一套用于构建用户界面的渐进式JavaScript框架 什么是渐进式? Vue可以自底向上逐层地应用; 当构建简单应用时, 只需一个轻量小巧的核心库; 当构建复杂应用时, 可以引入各式各样的Vue插件 Vue具有以下特点: 采用组件化模式, 提高代码复用率且让代码更好维护 声明式编…