日志系统——性能测试

news2024/11/16 15:54:54

日志系统项目已经编写完成,在本节完成性能测试之后就正式结束了

 测试代码如下

#include "../logs/mjwlog.h"
#include <vector>
#include <thread>


//参数:日志器名称,线程数量,输出日志条数,单条日志大小
void perform(const std::string& loggername,const size_t thread_count,const size_t msg_count,const size_t msg_size)
{
    //1. 获取日志器
    mjwlog::Logger::ptr logger = mjwlog::LoggerManage::GetInstance().GetLogger(loggername);
    if(logger.get()==nullptr) return;
    //2. 创建日志信息
    std::string msg(msg_size,'#');
    //3. 创建多线程
    std::vector<double> cost_time;
    std::vector<std::thread> threads;
    size_t singal_thread_ologs=msg_count/thread_count;//单个线程需要输出的日志条数
    std::cout<<"总输出日志条数:"<<msg_count<<"条"<<" 输出日志总大小:"<<(msg_count*msg_size)/(1024*1024)<<" MB"<<std::endl;
    for(int i=0;i<thread_count;i++)
    {
        threads.emplace_back([&,i,singal_thread_ologs](){
            //4. 开始时间
            auto start=std::chrono::high_resolution_clock::now();
            //5. 开始输出
            for(int j=0;j<singal_thread_ologs;j++)
            {
                logger->fatal("%s",msg.c_str());
                //std::cout<<"输出"<<std::endl;
            }
            //6. 结束时间
            auto end=std::chrono::high_resolution_clock::now();
            //记录结果
            std::chrono::duration<double> result=end-start;
            cost_time.push_back(result.count());
            //输出该线程测试信息
            std::cout<<"线程"<<i<<" 输出日志数量:"<<singal_thread_ologs<<" 耗时: " << result.count() << "s\n";
        });
    }
    //回收线程
    for(int i=0;i<thread_count;i++)
    {
        threads[i].join();
    }
    //7.计算总耗时
    //多线程输出时,由于多个线程并非执行,因此计算总耗时并不是所有线程所消耗时间相加
    //而是取最大耗时
    double max_cost_time=cost_time[0];
    for(int i=0;i<thread_count;i++)
    {
        max_cost_time=max_cost_time<cost_time[i]?cost_time[i]:max_cost_time;
    }
    std::cout<<max_cost_time<<std::endl;
    size_t msg_pre_sec=msg_count/max_cost_time;//每秒打印日志条数
    size_t size_pre_sec=(msg_count*msg_size)/(max_cost_time*1024*1024);//每秒输出大小,单位MB
    
    //8. 输出结果

    std::cout<<"总耗时:"<<max_cost_time<<"s"<<std::endl;
    std::cout<<"每秒输出日志条数:"<<msg_pre_sec<<std::endl;
    std::cout<<"每秒输出大小:"<<size_pre_sec<<" MB"<<std::endl;
}

//同步日志器性能测试
void sync_perform()
{
    std::unique_ptr<mjwlog::LoggerBuild> lb(new mjwlog::GlobalLoggerBuild());
    lb->BuildDefaultLevel(mjwlog::LogLevel::level::WARN);
    lb->BuildFormat("%m%n");
    lb->BuildLoggerName("sync_logger");
    lb->BuildSink<mjwlog::FileSink>("./logfile/sync_logger.log");    
    lb->BuildLoggerType(mjwlog::type::SyncLogger);
    lb->build();
    //单线程
    //perform("sync_logger",1,1000000,100);
    //多线程
    perform("sync_logger",5,1000000,100);

}

//异步日志器性能测试
void async_perform()
{
    std::unique_ptr<mjwlog::LoggerBuild> lb(new mjwlog::GlobalLoggerBuild());
    lb->BuildDefaultLevel(mjwlog::LogLevel::level::WARN);
    lb->BuildFormat("%m%n");
    lb->BuildLoggerName("async_logger");
    lb->BuildSink<mjwlog::FileSink>("./logfile/async_logger.log");    
    lb->BuildLoggerType(mjwlog::type::AsyncLogger);
    lb->BuileUnsafeBuffer();//开启不安全测试模式
    lb->build();
    
    //单线程
    //perform("async_logger",1,1000000,100);
    //多线程
    perform("async_logger",5,1000000,100);
}


int main()
{
    async_perform();
    return 0;
}

主要测试要素:同步/异步 & 单线程/多线程

1. 输出100w+条指定长度日志所需时间

2. 每秒可以输出多少条日志

3. 每秒可以输出多少大小的日志(MB)

测试环境

腾讯云服务器

CPU:2核

内存:2G

硬盘:SSD运营盘 40G

系统:CentOS 7.6 64bit

 同步日志下单线程

 同步日志下多线程

异步日志下单线程

 异步日志下多线程

 从上面的实验数据我们发现,在单线程的情况下异步日志器还没有同步日志器效率高,这是因为现在的I/O操作在用户态都会有缓冲区进行缓冲,因此我们当前测试用例看起来的同步实际上也是在操作内存,只有在缓冲区满了才会涉及到阻塞磁盘写入,而我们异步日志器效率比较低是因为单线程异步日志器中也存在大量的锁冲突,而同步日志器则没有,因此性能异步日志器性能有一定程度上的降低

 当我们切入到多线程后,发现同步日志器性能不但没有提升而且还下降了,而异步日志器性能则有有效的提升,这是因为同步日志器要将日志亲自写入到磁盘中,因此其性能上限收到磁盘读写速度的限制,即使多线程也难以提升,反而因为锁冲突导致性能下降;而异步日志器上限则是CPU的处理性能,日志输出时不会因为落地而阻塞,因此多线程下有了显著提升。

当然这是在云服务器的渣机下的实验数据,如果在各位自己的电脑上实验相信能够更上一层楼。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nginx(七十八)nginx配置http2

一 ngx_http_v2模块 1、本文不讲解HTTP2的知识2、只讲解nginx中如何配置HTTP2 ① 前置条件 1、openssl的版本必须在1.0.2e及以上2、开启https加密,目前http2.0只支持开启了https的网站编译选项&#xff1a;--with-http_ssl_module --with-http_v2_module 特点&#xff1a…

【翻译】RISC-V指令集手册第Ⅱ卷:特权体系结构

第三章 机器级ISA&#xff0c;版本1.11 本章描述RISC-V系统中最高权限的机器模式(M-mode)下的机器级操作。M模式用于对硬件平台的低级访问&#xff0c;是复位时进入的第一个模式。M模式还可以用于实现在硬件中直接实现过于困难或代价过高的特性。RISC-V机器级ISA包含一个公共核…

Android Studio升级到Android API 33版本后,XML布局输入没有提示

低版本的Android Studio升级到Android API 33版本后&#xff0c;XML布局输入没有提示。查一下我目前使用的Android Studio 是2021年发布&#xff0c;而Android API 33是2022年发布的&#xff0c;这是由低版本升级到高版本造成不兼容的问题。解决方法有两种&#xff1a; 第一种…

1 Hadoop入门

1.Hadoop是什么&#xff1f; (1)Hadoop是一个由Apache基金会所开发的分布式系统基础架构。 (2)主要解决&#xff0c;海量数据的存储和海量数据的分析计算问题。 (3)广义上来说&#xff0c;Hadoop通常是指一个更广泛的概念——Hadoop生态圈 2.Hadoop的优势 3 Hadoop组成 4 HDF…

如何将储存在Mac或PC端的PDF文件传输到移动设备呢?

iMazing是一款iOS设备管理软件&#xff0c;用户借助它可以将iPad或iPhone上的文件备份到PC或Mac上&#xff0c;还能实现不同设备之间的文件传输&#xff0c;能很大程度上方便用户进行文件管理。 在阅读方面&#xff0c;iPad和iPhone是阅读PDF的优秀选择&#xff0c;相较于Mac或…

IDEA常用配置之类Tab页多行显示

文章目录 IDEA常用配置之类Tab页多行显示 IDEA常用配置之类Tab页多行显示 默认在Idea中打开类过多&#xff0c;后面会隐藏显示&#xff0c;这里修改配置&#xff0c;将类设置为多行显示&#xff0c;方便查找已经打开的类 修改后显示样式

抢先体验|乐鑫推出 ESP32-S3-BOX-3 新一代开源 AIoT 开发套件

乐鑫科技 (688018.SH) 非常高兴地宣布其开发套件阵容的最新成员 ESP32-S3-BOX-3。这款完全开源的 AIoT 应用开发套件搭载乐鑫高性能 ESP32-S3 AI SoC&#xff0c;旨在突破传统开发板&#xff0c;成为新一代开发工具的引领者。 【乐鑫新品抢先体验】ESP32-S3-BOX-3 新一代开源 A…

ctfshow-web13 文件上传

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先看到是一个上传页面&#xff0c;测试其他无果&#xff0c;遂进行目录遍历&#xff0c;发现upload.php.bak文件 可以看到这里的限制条件&#xff0c;大小&#xff0c;以及内容&#xff0c;这里可以使用.use…

DataWhale夏令营第三期-CV赛道-第三次打卡

第三次打卡 使用resnet18训练精度&#xff1a;评分0.74 使用resnet34精度&#xff1a;评分0.74 使用resnet50精度&#xff1a;评分0.21&#xff0c;不知道为什么网络层数高反而准确度下降&#xff0c;猜测层数多丢失了一些特征信息。

数据结构入门 — 链表详解_双向链表

前言 数据结构入门 — 双向链表详解* 博客主页链接&#xff1a;https://blog.csdn.net/m0_74014525 关注博主&#xff0c;后期持续更新系列文章 文章末尾有源码 *****感谢观看&#xff0c;希望对你有所帮助***** 系列文章 第一篇&#xff1a;数据结构入门 — 链表详解_单链表…

【每日一题】1448. 统计二叉树中好节点的数目

【每日一题】1448. 统计二叉树中好节点的数目 1448. 统计二叉树中好节点的数目题目描述解题思路 1448. 统计二叉树中好节点的数目 题目描述 给你一棵根为 root 的二叉树&#xff0c;请你返回二叉树中好节点的数目。 「好节点」X 定义为&#xff1a;从根到该节点 X 所经过的节…

微信小程序如何实现页面传参和页面传递多个参数

前言 只要你的小程序超过一个页面那么可能会需要涉及到页面参数的传递&#xff0c;下面我总结了 4 种页面方法。 下面时多个参数页面传参的方式 let loveJSON.stringify(this.data.totle);let youJSON.stringify(this.data.totleId)let csdnJSON.stringify(this.data.totleP…

命令全局安装 ts

1.全局安装 typeScript编译 npm install -g typescript2.查看版本 tsc-v安装成功的画面

win10+wsl2+Ubuntu20.2+Pycharm+WSL解释器

目的&#xff1a;创建一个ubuntu系统下的python解释器&#xff0c;作为win平台下的pycharm的解释器。 这样做的好处是可以直接在win系统里操作文件&#xff0c;相比于linux方便一点&#xff0c;而且也不用对wsl的子系统进行迁移。 一、安装前准备 1. 设置-Windows更新-window…

JDK1.8 安装教程(linux)

一、 检查当前系统是否已安装JDK 通过命令java –version 如果有出现如下图提示表示有安装&#xff0c;则无需再安装 二、 安装JDK 通过JDK官网https://www.oracle.com/上下载需要的JDK 版本&#xff0c;下载完成后上传到linux 系统上指定的文件夹下。&#xff08;可以用宝…

copy is all you need前向绘图 和疑惑标记

疑惑的起因 简化前向图 GPT4解释 这段代码实现了一个神经网络模型&#xff0c;包含了BERT、GPT-2和MLP等模块。主要功能是给定一个文本序列和一个查询序列&#xff0c;预测查询序列中的起始和结束位置&#xff0c;使其对应文本序列中的一个短语。具体实现细节如下&#xff1a…

面向对象的理解

想要对象了&#xff1f;没问题&#xff0c;new一个就好了。 但是&#xff0c;new太多对象&#xff0c;对象也会生气的哦。 你瞧&#xff0c;她来了 从两段代码发现端倪 我们来计算一个矩形的面积&#xff0c;看看这两段代码有什么区别呢&#xff1f; 第一段&#xff1a; con…

并发-线程池

阻塞队列 笔记地址 点击进入 队列&#xff1a;先进先出 限定在一端进行插入&#xff0c;一端进行删除 出队为队头&#xff0c;入队为队尾 阻塞队列 BlockingQueue Queue接口继承Collection接口添加元素&#xff1a;add()&#xff0c;队列满了对抛出异常offer()&#xff0c;队…

【二分】搜索旋转数组

文章目录 不重复数组找最小值&#xff0c;返回下标重复数组找最小值&#xff0c;返回下标不重复数组找target&#xff0c;返回下标重复数组找target&#xff0c;返回bool重复数组找target&#xff0c;返回下标 不重复数组找最小值&#xff0c;返回下标 class Solution {public …

js中作用域的理解?

1.作用域 作用域&#xff0c;即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变量和其他资源的可见性 举个例子 function myFunction() {let inVariable "函数内部变量"; } myFunction();//要先执行这…