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

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

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

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

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言
主要内容对项目的目录结构进行了梳理,以及测试了代码的性能,分别在云服务器和本地的虚拟机上进行了测试

文章目录

1.项目目录结构梳理

  • Example

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

  • Extend

    存储我们的拓展代码文件

  • Logs

    存储项目的所有的头文件

  • PreSturdy

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

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

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

2.1测试工具的编写

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

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

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

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

实现

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

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

cpp 复制代码
#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内存)
①云服务器环境下:
②本地虚拟机:

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

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

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

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

相关推荐
van叶~43 分钟前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
金池尽干44 分钟前
设计模式之——观察者模式
观察者模式·设计模式
knighthood20011 小时前
解决:ros进行gazebo仿真,rviz没有显示传感器数据
c++·ubuntu·ros
也无晴也无风雨1 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
半盏茶香1 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
小堇不是码农1 小时前
在VScode中配置C_C++环境
c语言·c++·vscode
Jack黄从零学c++2 小时前
C++ 的异常处理详解
c++·经验分享
捕鲸叉7 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer7 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq7 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端