-
Notifications
You must be signed in to change notification settings - Fork 111
Description
I worked with Boost.Log library and encountered a huge performance impact in case when all content passed to the logger supposed to be filtered.
I reduced the logger to the simplest one with a console backend and the result remained the same.
Here is the sample code:
#include <boost/log/sources/severity_feature.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/common.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/phoenix/bind.hpp>
enum severity_level
{
critical,
info,
trace
};
BOOST_LOG_ATTRIBUTE_KEYWORD(severity_level_kw, "Severity", severity_level)
using backend_type = boost::log::sinks::synchronous_sink<boost::log::sinks::basic_text_ostream_backend<char>>;
bool filter_impl(severity_level lvl) { return lvl < trace; }
bool filter(const boost::log::value_ref<severity_level, tag::severity_level_kw> & lvl) {
return filter_impl(*lvl);
}
void logging_function() {
auto sink = boost::make_shared<backend_type>();
sink->set_filter(boost::phoenix::bind(&filter, severity_level_kw.or_none()));
sink->locked_backend()->add_stream(boost::shared_ptr<std::ostream>(&std::cout, boost::null_deleter{}));
boost::log::core::get()->add_sink(std::move(sink));
boost::log::sources::severity_logger<severity_level> slg;
for(int i = 0; i < 100000000; ++i) {
// I expect this line only applies the filter and does nothing else since trace-messages supposed to be filtered
BOOST_LOG_SEV(slg, trace) << "Trace message: " << i;
}
}
int main()
{
logging_function();
return 0;
}
This simple program works for ~14 seconds.
But if I change the loop like this:
for(int i = 0; i < 100000000; ++i) {
if(filter_impl(trace))
std::cout << "Debug message: " << i << "\n";
}
the program completes instantly as it supposed to. And it's what I expect the log library should do.
I profiled the program with dotTrace and here is the result
As you can see filter function takes only 95ms and the rest time goes to another stuff including memory allocations which I wouldn't expect to see.
This problem makes Boost.Log unusable in cases when performance is a priority.
As a hot-fix one can filter records manually by introducing a special macro, for example.
But is it worth expecting this issue will be fixed?
