Skip to content

Instantly share code, notes, and snippets.

@frankyueh
Last active January 8, 2018 11:12
Show Gist options
  • Save frankyueh/c1a9a7e3d555982800379ac69658b461 to your computer and use it in GitHub Desktop.
Save frankyueh/c1a9a7e3d555982800379ac69658b461 to your computer and use it in GitHub Desktop.
function pointer is not better than virtual function
#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