muduo库学习笔记十五:base库之日志库二 LogStream类

LogStream类

muduo没有用到标准库的iostream,而是自己写的LogStream类,这主要是出于性能。LogStream类,让它如同C++的标准输出流对象cout,能用<<符号接收输入,cout是输出到终端,而LogStream类是把输出保存自己内部的缓冲区,可以让外部程序把缓冲区的内容重定向输出到不同的目标,如文件、终端、socket。

LogStream类图

LogStream类重载了一系列的<<操作符,主要作用是将内容输入到FixedBuffer缓冲区中(不是终端也不是文件或socket),而从缓冲区到终端/文件操作是在Logger类中完成的。在Logger类析构时,调用用户定义的OutputFunc xx函数和FlushFunc xx函数来完成最终的终端/文件显示。

FixedBuffer 类:缓冲区模板类,类中SIZE不是类型参数,而是缓冲区大小。

类图

缓冲区具体结构如下:

  知识点

1、void bzero() { ::bzero(data_, sizeof data_); }//将数据清0,将字符串s的前n个字节置为0,一般来说n通常取sizeof(s),将整块空间清零。

2、#pragma GCC diagnostic ignored "-Wtype-limits"//忽略这个编译选项/3、uintptr_t 对32位平台就是unsigned int 对于64位平台就是unsigned long int

4、Fmt类,在构造时,就会断言判断 BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value == true);//断言T是算术类型

另外Fmt显示实例化后,相当于定义了11个类

5、函数说明:

template<typename T> void LogStream::formatInteger(T v)//成员模板 将整数转换为字符串存放进去--当前指针的位置

template<typename T> size_t convert(char buf[], T value)//将一个整数以字符串形式转换到buf中

void LogStream::staticCheck()//检查不同类型最大值的位数是否合法,124-->3位

LogStream& LogStream::operator<<(int v)//将一个整数保存进缓冲区中

6、这里还需要注意一个是<sting.h>与<string>是两个完全不同的头文件。

7、#include <muduo/base/StringPiece.h> 用于实现高效的字符串传递
    //这里即可使用const char*、也可以使用std::string类型作为参数
    //不用void foo(const char* x);因为string需要进行转换才能传递进去 .c_str()
    //不用void foo(const String& x);因为char* 转换为string,涉及到内存拷贝,效率低下

StringPiece中需要注意的是:STL中为了提供通用的操作而又不损失效率,我们用到了一个特殊的技巧,叫traits编程技巧。具体来说,traits就是通过定义一些结构体或类,并利用模板特化和偏特化的能力,给类赋予一些特性,这些特性根据类型的不同而异。在程序设计中可以使用这些traits来判断一个类型的一些特性,引发C++的函数重载机制实现同一操作因类型不同而异的效果。

8、注意muduo中的string

#ifdef MUDUO_STD_STRING
using std::string;
#else  // !MUDUO_STD_STRING
typedef __gnu_cxx::__sso_string string;//接口相同,内部实现不同
#endif

使用示例1

#include <muduo/base/LogStream.h>

#include <limits>
#include <stdint.h>

//#define BOOST_TEST_MODULE LogStreamTest
#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

using muduo::string;

BOOST_AUTO_TEST_CASE(testLogStreamBooleans)//bool型测试
{
  muduo::LogStream os;//构造一个LogStream对象os
  const muduo::LogStream::Buffer& buf = os.buffer();
  BOOST_CHECK_EQUAL(buf.asString(), string(""));
  os << true;
  BOOST_CHECK_EQUAL(buf.asString(), string("1"));
  os << '\n';
  BOOST_CHECK_EQUAL(buf.asString(), string("1\n"));
  os << false;
  BOOST_CHECK_EQUAL(buf.asString(), string("1\n0"));
}

测试用例,通过boost单元测试框架实现,使用前应该确保libboost-test-dev库已经安装(之前安装的是libboost-dev基础库)

使用示例2

#include <muduo/base/LogStream.h>
#include <muduo/base/Timestamp.h>

#include <sstream>
#include <stdio.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>

using namespace muduo;

const size_t N = 1000000;

#pragma GCC diagnostic ignored "-Wold-style-cast"//忽略该编译选项

template<typename T>
void benchPrintf(const char* fmt)
{
  char buf[32];
  Timestamp start(Timestamp::now());
  for (size_t i = 0; i < N; ++i)
    snprintf(buf, sizeof buf, fmt, (T)(i));
  Timestamp end(Timestamp::now());

  printf("benchPrintf %f\n", timeDifference(end, start));
}

template<typename T>
void benchStringStream()
{
  Timestamp start(Timestamp::now());
  std::ostringstream os;

  for (size_t i = 0; i < N; ++i)
  {
    os << (T)(i);
    os.seekp(0, std::ios_base::beg);
  }
  Timestamp end(Timestamp::now());

  printf("benchStringStream %f\n", timeDifference(end, start));
}

template<typename T>
void benchLogStream()
{
  Timestamp start(Timestamp::now());
  LogStream os;
  for (size_t i = 0; i < N; ++i)
  {
    os << (T)(i);
    os.resetBuffer();
  }
  Timestamp end(Timestamp::now());

  printf("benchLogStream %f\n", timeDifference(end, start));
}
//性能基准测试
int main()
{
  benchPrintf<int>("%d");

  puts("int");
  benchPrintf<int>("%d");
  benchStringStream<int>();
  benchLogStream<int>();

  puts("double");
  benchPrintf<double>("%.12g");
  benchStringStream<double>();
  benchLogStream<double>();

  puts("int64_t");
  benchPrintf<int64_t>("%" PRId64);
  benchStringStream<int64_t>();
  benchLogStream<int64_t>();

  puts("void*");
  benchPrintf<void*>("%p");
  benchStringStream<void*>();
  benchLogStream<void*>();

}

验证使用printf、stringstream以及logstream类三者进行输出的效率。

输出

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值