Last active
January 8, 2018 11:12
-
-
Save frankyueh/c1a9a7e3d555982800379ac69658b461 to your computer and use it in GitHub Desktop.
function pointer is not better than virtual function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstring> | |
namespace w_virtual { | |
class LogWriterAdaptor | |
{ | |
public: | |
typedef char char_t; | |
LogWriterAdaptor() {} | |
virtual ~LogWriterAdaptor() {} | |
virtual size_t operator()(const char_t *_writeln) = 0; | |
}; | |
template <class logWriterT> | |
class LogWriterAdaptorType : public LogWriterAdaptor | |
{ | |
logWriterT & log_writer_; | |
public: | |
LogWriterAdaptorType(logWriterT &_log_writer) | |
: log_writer_(_log_writer) | |
{} | |
virtual size_t operator()(const char_t *_writeln) | |
{ | |
return log_writer_.write_log(_writeln); | |
} | |
}; | |
} // namespace w_virtual | |
namespace wo_virtual { | |
class LogWriterAdaptor | |
{ | |
public: | |
typedef char char_t; | |
typedef size_t (*log_write_t)(void *_adaptor, const char_t *_writeln); | |
LogWriterAdaptor(log_write_t _log_write) : log_write_(_log_write) {} | |
~LogWriterAdaptor() {} | |
size_t operator()(const char_t *_writeln) | |
{ | |
return log_write_(this, _writeln); | |
} | |
protected: | |
log_write_t log_write_; | |
}; | |
template <class logWriterT> | |
class LogWriterAdaptorType : public LogWriterAdaptor | |
{ | |
logWriterT & log_writer_; | |
static size_t write(void *_adaptor, const char_t *_writeln) | |
{ | |
return static_cast<LogWriterAdaptorType*>(_adaptor)->log_writer_.write_log(_writeln); | |
} | |
public: | |
LogWriterAdaptorType(logWriterT &_log_writer) | |
: LogWriterAdaptor(&LogWriterAdaptorType::write) | |
, log_writer_(_log_writer) | |
{} | |
}; | |
} // namespace wo_virtual | |
class SomeLogWriter | |
{ | |
public: | |
typedef char char_t; | |
size_t write_log(const char_t *_writeln) | |
{ | |
return std::strlen(_writeln); | |
} | |
}; | |
static void WithVirtual(benchmark::State& state) { | |
// Code inside this loop is measured repeatedly | |
using namespace wo_virtual; | |
SomeLogWriter log_writer; | |
LogWriterAdaptorType<SomeLogWriter> typed_adaptor(log_writer); | |
LogWriterAdaptor &adaptor = typed_adaptor; | |
for (auto _ : state) { | |
size_t ret = adaptor("hello"); | |
// Make sure the variable is not optimized away by compiler | |
benchmark::DoNotOptimize(ret); | |
} | |
} | |
// Register the function as a benchmark | |
BENCHMARK(WithVirtual); | |
static void WithoutVirtual(benchmark::State& state) { | |
// Code inside this loop is measured repeatedly | |
using namespace w_virtual; | |
SomeLogWriter log_writer; | |
LogWriterAdaptorType<SomeLogWriter> typed_adaptor(log_writer); | |
LogWriterAdaptor &adaptor = typed_adaptor; | |
for (auto _ : state) { | |
size_t ret = adaptor("hello"); | |
// Make sure the variable is not optimized away by compiler | |
benchmark::DoNotOptimize(ret); | |
} | |
} | |
BENCHMARK(WithoutVirtual); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment