From ba2b6aea25af96d4f01d2b91d49c5619a5c71ec0 Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 20 Mar 2014 03:47:57 +0200 Subject: [PATCH] fast_buf\! --- example/example.cpp | 7 ++- include/c11log/common_types.h | 1 + include/c11log/details/fast_oss.h | 66 ++++++++++++++++----------- include/c11log/details/flush_helper.h | 4 +- include/c11log/details/line_logger.h | 2 +- include/c11log/details/os.h | 4 +- include/c11log/formatter.h | 7 +-- include/c11log/logger.h | 9 ++-- include/c11log/sinks/async_sink.h | 10 ++-- include/c11log/sinks/base_sink.h | 6 +-- include/c11log/sinks/console_sinks.h | 4 +- include/c11log/sinks/file_sinks.h | 10 ++-- 12 files changed, 75 insertions(+), 55 deletions(-) diff --git a/example/example.cpp b/example/example.cpp index a762a33d..fd434a2b 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -15,14 +15,13 @@ using namespace std::chrono; using namespace c11log; using namespace utils; - int main(int argc, char* argv[]) { - if(argc || argv) {}; + if(argc || argv) {}; auto fsink = std::make_shared("log", "txt", 1024*1024*50 , 5, 0); - //auto fsink = std::make_shared("simplelog", "txt"); + //auto fsink = std::make_shared("simplelog", "txt"); auto null_sink = std::make_shared(); @@ -35,7 +34,7 @@ int main(int argc, char* argv[]) auto start = system_clock::now(); - const unsigned int howmany = 3000000; + const unsigned int howmany = 5000000; for(unsigned int i = 0; i < howmany ; i++) my_logger.info() << "Hello logger " << i; diff --git a/include/c11log/common_types.h b/include/c11log/common_types.h index 4978a090..8fe6efcc 100644 --- a/include/c11log/common_types.h +++ b/include/c11log/common_types.h @@ -6,6 +6,7 @@ namespace c11log { typedef std::chrono::system_clock log_clock; +typedef std::pair bufpair_t; namespace level { diff --git a/include/c11log/details/fast_oss.h b/include/c11log/details/fast_oss.h index 5f0119c3..33b12a26 100644 --- a/include/c11log/details/fast_oss.h +++ b/include/c11log/details/fast_oss.h @@ -2,8 +2,7 @@ // Faster than ostringstream--returns its string by ref -#include -#include +#include "c11log/details/fast_buf.h" namespace c11log { @@ -12,7 +11,7 @@ namespace details class str_devicebuf:public std::streambuf { -public: +public: str_devicebuf() = default; ~str_devicebuf() = default; @@ -21,15 +20,21 @@ public: str_devicebuf& operator=(const str_devicebuf&) = delete; str_devicebuf& operator=(str_devicebuf&&) = delete; - + /* const std::string& str_ref() const { return _str; } + */ + bufpair_t buf() + { + return _fastbuf.get(); + } void reset_str() { - _str.clear(); + //_str.clear(); + _fastbuf.clear(); } protected: @@ -38,32 +43,35 @@ protected: return 0; } - // copy the give buffer into the accumulated string. - // reserve initially 128 bytes which should be enough for common log lines - std::streamsize xsputn(const char_type* s, std::streamsize count) override - { - if(_str.capacity() < k_initial_reserve) - { - _str.reserve(k_initial_reserve); - } - _str.append(s, static_cast(count)); + // copy the give buffer into the accumulated string. + // reserve initially 128 bytes which should be enough for common log lines + std::streamsize xsputn(const char_type* s, std::streamsize count) override + { + /* + if(_str.capacity() < k_initial_reserve) + { + _str.reserve(k_initial_reserve); + } + _str.append(s, static_cast(count)); + */ + _fastbuf.append(s, static_cast(count)); return count; } int_type overflow(int_type ch) override { - bool not_eofile = traits_type::not_eof(ch); + bool not_eofile = traits_type::not_eof(ch); if (not_eofile) - { - char c = traits_type::to_char_type(ch); + { + char c = traits_type::to_char_type(ch); xsputn(&c, 1); - } - return not_eofile; + } + return not_eofile; } private: - std::string _str; - static constexpr std::streamsize k_initial_reserve = 128; + //std::string _str; + fast_buf<128> _fastbuf; }; class fast_oss:public std::ostream @@ -75,15 +83,21 @@ public: fast_oss(const fast_oss& other) = delete; fast_oss(fast_oss&& other) = delete; fast_oss& operator=(const fast_oss& other) = delete; - + /* const std::string& str_ref() const { return _dev.str_ref(); } - void reset_str() - { - _dev.reset_str(); - } + */ + bufpair_t buf() + { + return _dev.buf(); + } + + void reset_str() + { + _dev.reset_str(); + } private: str_devicebuf _dev; diff --git a/include/c11log/details/flush_helper.h b/include/c11log/details/flush_helper.h index a5743219..b9ed080d 100644 --- a/include/c11log/details/flush_helper.h +++ b/include/c11log/details/flush_helper.h @@ -13,9 +13,9 @@ public: _flush_every(flush_every), _write_counter(0) {}; - void write(std::ofstream& ofs, const std::string& msg) + void write(std::ofstream& ofs, const bufpair_t& msg) { - ofs.write(msg.c_str(), msg.size()); + ofs.write(msg.first, msg.second); if(++_write_counter == _flush_every) { ofs.flush(); diff --git a/include/c11log/details/line_logger.h b/include/c11log/details/line_logger.h index cecea1f9..2424551a 100644 --- a/include/c11log/details/line_logger.h +++ b/include/c11log/details/line_logger.h @@ -50,7 +50,7 @@ public: if (_enabled) { _oss << os::eol(); - _callback_logger->_log_it(_oss.str_ref(), _level); + _callback_logger->_log_it(_oss.buf(), _level); } } diff --git a/include/c11log/details/os.h b/include/c11log/details/os.h index 2161e15f..7a388c2a 100644 --- a/include/c11log/details/os.h +++ b/include/c11log/details/os.h @@ -50,9 +50,9 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2) constexpr inline const char* eol() { #ifdef _WIN32 - return "\r\n"; + return "\r\n"; #else - return "\n"; + return "\n"; #endif } } //os diff --git a/include/c11log/formatter.h b/include/c11log/formatter.h index 695a7c18..37f32330 100644 --- a/include/c11log/formatter.h +++ b/include/c11log/formatter.h @@ -88,9 +88,10 @@ inline void c11log::formatters::default_formatter::_format_time(const log_clock: time_oss << tm_now.tm_sec << ']'; //Cache the resulted string and its size s_cache_time_t = tp_time_t; - const std::string &s = time_oss.str_ref(); - std::memcpy(s_cache_str, s.c_str(), s.size()); - s_cache_size = s.size(); + //const std::string &s = time_oss.str_ref(); + bufpair_t buf = time_oss.buf(); + std::memcpy(s_cache_str, buf.first, buf.second); + s_cache_size = buf.second; } dest.write(s_cache_str, s_cache_size); } diff --git a/include/c11log/logger.h b/include/c11log/logger.h index 935a7252..2d7f01c7 100644 --- a/include/c11log/logger.h +++ b/include/c11log/logger.h @@ -21,6 +21,7 @@ namespace c11log namespace details { class line_logger; +template class fast_buf; } @@ -67,7 +68,7 @@ private: sinks_vector_t _sinks; std::atomic_int _atomic_level; - void _log_it(const std::string& msg, const level::level_enum level); + void _log_it(const bufpair_t& buf, const level::level_enum level); }; @@ -80,6 +81,7 @@ logger& get_logger(const std::string& name); // Logger inline implementation // #include "details/line_logger.h" +#include "details/fast_buf.h" inline c11log::logger::logger(const std::string& name, formatter_ptr f, sinks_init_list sinks_list) : @@ -145,10 +147,11 @@ inline bool c11log::logger::should_log(c11log::level::level_enum level) const { return level >= _atomic_level.load(); } -inline void c11log::logger::_log_it(const std::string& msg, const level::level_enum level) + +inline void c11log::logger::_log_it(const bufpair_t& buf, const level::level_enum level) { for (auto &sink : _sinks) - sink->log(msg, level); + sink->log(buf, level); } // Static factory function diff --git a/include/c11log/sinks/async_sink.h b/include/c11log/sinks/async_sink.h index 340eb198..d99e5b20 100644 --- a/include/c11log/sinks/async_sink.h +++ b/include/c11log/sinks/async_sink.h @@ -28,7 +28,7 @@ public: protected: - void _sink_it(const std::string& msg) override; + void _sink_it(const bufpair_t& msg) override; void _thread_loop(); private: @@ -57,9 +57,10 @@ inline c11log::sinks::async_sink::~async_sink() { _shutdown(); } -inline void c11log::sinks::async_sink::_sink_it(const std::string& msg) +inline void c11log::sinks::async_sink::_sink_it(const bufpair_t& msg) { - _q.push(msg); + std::string s {msg.first, msg.first+msg.second}; + _q.push(s); } inline void c11log::sinks::async_sink::_thread_loop() @@ -71,9 +72,10 @@ inline void c11log::sinks::async_sink::_thread_loop() { if (_q.pop(msg, pop_timeout)) { + bufpair_t buf(msg.data(), msg.size()); for (auto &sink : _sinks) { - sink->log(msg, static_cast(_level.load())); + sink->log(buf, static_cast(_level.load())); if (!_active) return; } diff --git a/include/c11log/sinks/base_sink.h b/include/c11log/sinks/base_sink.h index 600fc251..a64320dc 100644 --- a/include/c11log/sinks/base_sink.h +++ b/include/c11log/sinks/base_sink.h @@ -22,7 +22,7 @@ public: base_sink(const base_sink&) = delete; base_sink& operator=(const base_sink&) = delete; - void log(const std::string &msg, level::level_enum level) + void log(const bufpair_t &msg, level::level_enum level) { if (level >= _level) { @@ -36,14 +36,14 @@ public: } protected: - virtual void _sink_it(const std::string& msg) = 0; + virtual void _sink_it(const bufpair_t& msg) = 0; std::atomic _level {level::INFO}; }; class null_sink:public base_sink { protected: - void _sink_it(const std::string& ) override + void _sink_it(const bufpair_t& ) override { } }; diff --git a/include/c11log/sinks/console_sinks.h b/include/c11log/sinks/console_sinks.h index 3fe8486e..6686e7b2 100644 --- a/include/c11log/sinks/console_sinks.h +++ b/include/c11log/sinks/console_sinks.h @@ -19,10 +19,10 @@ public: virtual ~console_sink() = default; protected: - virtual void _sink_it(const std::string& msg) override + virtual void _sink_it(const bufpair_t& msg) override { std::lock_guard lock(_mutex); - _ostream << msg; + _ostream.write(msg.first, msg.second); } std::ostream& _ostream; diff --git a/include/c11log/sinks/file_sinks.h b/include/c11log/sinks/file_sinks.h index d5af992f..4e68e7d4 100644 --- a/include/c11log/sinks/file_sinks.h +++ b/include/c11log/sinks/file_sinks.h @@ -26,7 +26,7 @@ public: { } protected: - void _sink_it(const std::string& msg) override + void _sink_it(const bufpair_t& msg) override { std::lock_guard lock(_mutex); _flush_helper.write(_ofstream, msg); @@ -59,14 +59,14 @@ public: } protected: - void _sink_it(const std::string& msg) override + void _sink_it(const bufpair_t& msg) override { std::lock_guard lock(_mutex); - _current_size += msg.length(); + _current_size += msg.second; if (_current_size > _max_size) { _rotate(); - _current_size = msg.length(); + _current_size = msg.second; } _flush_helper.write(_ofstream, msg); } @@ -132,7 +132,7 @@ public: } protected: - void _sink_it(const std::string& msg) override + void _sink_it(const bufpair_t& msg) override { std::lock_guard lock(_mutex); if (std::chrono::system_clock::now() >= _midnight_tp)