首頁 > 軟體

c++的glog與spdlog的效能對比測試分析

2022-05-20 13:12:37

問題:

之前看到有的博文說glog效能很好,效率很高,當時第一反應是“這個結論是几几年的?”,可惜博文都是各種抄襲和轉載,不容易找到結論出處,我一直很懷疑它的寫入吞吐效能。

之前作為學習優秀的程式碼案例,略看過glog的原始碼。它是執行緒同步的方式記錄和寫入,每次呼叫紀錄檔的地方都要建立和釋放紀錄檔器,確實在每次建立物件時並沒有建立額外快取空間,而是複用第一次建立的記憶體空間,這相比於每次建立申請新記憶體而言,效率很高,難道高效能僅僅指這個?可惜我自己的C++水平也就是應用程式開發,暫時是沒有能力寫出這類高效能基礎工具庫的。

所以,不如直接執行以下,從結果上比一比就知道。

測試內容:

今天把spdlog紀錄檔庫,也用了下,並且和glog做了簡單對比。spdlog在引入到專案中的成本很低,只要引入標頭檔案,glog還需要設定下,如果是第一次,還需要額外編譯一個glog版本。

基於十萬筆紀錄檔資料,大概也就10MB不到。

測試結果如下,是在一臺低配的伺服器上跑的,硬碟還是機械的scsi介面,後面給出測試程式碼,程式程式碼相同環境下執行:

在同步呼叫的場景下,spdlog比glog快,spdlog耗時0.135秒,glog耗時1.027秒,簡單非同步spdlog耗時0.158秒,普通ofstream流寫入0.252秒。

另外,在自己開發環境的電腦上用的是固態硬碟,結果如下:

在同步呼叫的場景下,spdlog比glog快,spdlog耗時0.057秒,glog耗時0.475秒,簡單非同步spdlog耗時0.093秒,普通ofstream流寫入0.112秒。

測試環境:

winserver 2012, 非固態硬碟

VS2019 ,C++11,spdlog-1.x,glog

glog測試程式碼如下:

#pragma once
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <spdlog/spdlog.h>
#include <logging.h>
#include <thread>
#include <spdlog/stopwatch.h>
using namespace google;
#ifdef _DEBUG
#pragma comment(lib, "glogd.lib")
#else
#pragma comment(lib, "glog.lib")
#endif // DEBUG
void testGlog2()
{
  int i = 0;
  spdlog::stopwatch sw;
  while (i < 100 * 1000)
  {
    LOG(INFO) << "async logger";
    i++;
  }
  LOG(INFO) << "testGlog Elapsed " << sw.elapsed().count();
}
void testGlog()
{
  // Start google log system:
  FLAGS_log_dir = ".\log\";
  google::InitGoogleLogging("loglog");
  google::SetLogDestination(google::GLOG_INFO, ".\logs\glog");
  google::SetStderrLogging(google::GLOG_FATAL);
  google::SetLogFilenameExtension("log_");
  FLAGS_colorlogtostderr = true;  // Set log color
  FLAGS_logbufsecs = 5;  // Set log output speed(s)
  FLAGS_max_log_size = 50;  // Set max log file size
  FLAGS_stop_logging_if_full_disk = true;  // If disk is full
  std::thread* t = new std::thread(testGlog2);
  t->join();
  google::ShutdownGoogleLogging();
}

spdlog非同步測試程式碼:

spdlog::info(" 建立basicFileLogger ");
        auto logger = spdlog::basic_logger_mt("basic_logger", "logs/basic_log.txt");
        logger->info("檔案建立完畢。");
        logger->set_pattern("[%Y-%m-%d %H:%M:%S.%f %z][thread %t][%n][%l]: %v");
        int i = 0;
        spdlog::stopwatch sw;
        while (i < 100 * 1000)
        {
            logger->info("basic_logger_mt logger");
            i++;
        }
        logger->info("asyncExample Elapsed {:.7}", sw);

普通io流寫入測試程式碼:

ofstream logger;
  logger.open("logs/fopen.txt", std::ios::out);
  int i = 0;
  spdlog::stopwatch sw;
  while (i < 100 * 1000)
  {
    logger << asctime(& spdlog::details::os::gmtime()) <<__FUNCTION__ << " "<<__LINE__ <<" " << ("async logger") <<"rn";
    i++;
  }
  logger<<"asyncExample Elapsed "<< sw.elapsed().count();
  logger.close();

總結:

僅僅從呼叫效能上看,spdlog耗時略低於glog。呼叫耗時從低到高如下:

spdlog同步 < spdlog非同步 < glog < 普通ofstream流

但是如果把計算機看作是工程化,則並不是簡單追求效能的。我覺得工程有一個因素是投入產出比。實際上,在平常專案中,我也用的是glog居多,因為glog很多的LOG_IF這類宏用起來很方便,對於紀錄檔吞吐效能也足夠使用,而且預設是dll方式使用,在多個獨立的元件dll之間可以使用同一個glog範例,只有少數模組需要儘量減少紀錄檔寫入影響的地方,用了spdlog非同步方式。

會不會是這個測試哪裡錯了?更多關於 c++ glog與spdlog效能對比的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com