From: JINMEI Tatuya Date: Tue, 6 Mar 2012 23:00:07 +0000 (-0800) Subject: [1603] added a new microbenchmark test for MessageRenderer implementations. X-Git-Tag: trac2351_base~226^2~116^2~121^2~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=beed5d700bd2ef38453f3a60e1bc2d4785c3bc68;p=thirdparty%2Fkea.git [1603] added a new microbenchmark test for MessageRenderer implementations. It compares the old and new versions, and one "dumb" renderer (which doesn't do any compression). --- diff --git a/src/lib/dns/benchmarks/Makefile.am b/src/lib/dns/benchmarks/Makefile.am index 0d7856ff72..44a9b19242 100644 --- a/src/lib/dns/benchmarks/Makefile.am +++ b/src/lib/dns/benchmarks/Makefile.am @@ -9,10 +9,15 @@ endif CLEANFILES = *.gcno *.gcda -noinst_PROGRAMS = rdatarender_bench +noinst_PROGRAMS = rdatarender_bench message_renderer_bench + rdatarender_bench_SOURCES = rdatarender_bench.cc rdatarender_bench_LDADD = $(top_builddir)/src/lib/dns/libdns++.la rdatarender_bench_LDADD += $(top_builddir)/src/lib/util/libutil.la rdatarender_bench_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la -rdatarender_bench_LDADD += $(SQLITE_LIBS) + +message_renderer_bench_SOURCES = message_renderer_bench.cc +message_renderer_bench_LDADD = $(top_builddir)/src/lib/dns/libdns++.la +message_renderer_bench_LDADD += $(top_builddir)/src/lib/util/libutil.la +message_renderer_bench_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la diff --git a/src/lib/dns/benchmarks/message_renderer_bench.cc b/src/lib/dns/benchmarks/message_renderer_bench.cc new file mode 100644 index 0000000000..480f373743 --- /dev/null +++ b/src/lib/dns/benchmarks/message_renderer_bench.cc @@ -0,0 +1,176 @@ +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include + +#include +#include +#include + +#include +#include + +using namespace std; +using namespace isc::util; +using namespace isc::bench; +using namespace isc::dns; + +namespace { +// This templated test performs rendering given set of names using +// a given (templated) MessageRenderer implementation. We can check the +// performance when we modify the renderer implementation by comparing the +// old and new implementation for the same data. +template +class MessageRendererBenchMark { +public: + MessageRendererBenchMark(const vector& names) : + names_(names) + {} + unsigned int run() { + renderer_.clear(); + vector::const_iterator it = names_.begin(); + const vector::const_iterator it_end = names_.end(); + for (; it != it_end; ++it) { + renderer_.writeName(*it); + } + // Make sure truncation didn't accidentally happen. + assert(!renderer_.isTruncated()); + return (names_.size()); + } +private: + T renderer_; + const vector& names_; +}; + +// +// Builtin benchmark data. +// +// This consists of all names contained in a response from a root server for +// the query for "www.example.com" (as of this implementing). +const char* const root_to_com_names[] = { + // question section + "www.example.com", + // authority section + "com", "a.gtld-servers.net", "com", "b.gtld-servers.net", + "com", "c.gtld-servers.net", "com", "d.gtld-servers.net", + "com", "e.gtld-servers.net", "com", "f.gtld-servers.net", + "com", "g.gtld-servers.net", "com", "h.gtld-servers.net", + "com", "i.gtld-servers.net", "com", "j.gtld-servers.net", + "com", "k.gtld-servers.net", "com", "l.gtld-servers.net", + "com", // owner name of DS + "com", // owner name of RRSIG(DS) + // additional section. a and b has both AAAA and A; others have A only. + "a.gtld-servers.net", "a.gtld-servers.net", + "b.gtld-servers.net", "b.gtld-servers.net", + "c.gtld-servers.net", "d.gtld-servers.net", "e.gtld-servers.net", + "f.gtld-servers.net", "g.gtld-servers.net", "h.gtld-servers.net", + "i.gtld-servers.net", "j.gtld-servers.net", "k.gtld-servers.net", + "l.gtld-servers.net", "m.gtld-servers.net", + NULL +}; + +// Names contained a typical "NXDOMAIN" response: the question, the owner +// name of SOA, and its MNAME and RNAME. +const char* const example_nxdomain_names[] = { + "www.example.com", "example.com", "ns.example.com", "root.example.com", + NULL +}; + +// Names contained a typical "SERVFAIL" response: only the question. +const char* const example_servfail_names[] = { + "www.example.com", NULL +}; + +// An experimental "dumb" renderer for comparison. It doesn't do any name +// compression. It simply ignores all setter method, returns a dummy value +// for getter methods, and write names to the internal buffer as plain binary +// data. +class DumbMessageRenderer : public AbstractMessageRenderer { +public: + virtual void clear() {} + virtual size_t getLengthLimit() const { return (512); } + virtual void setLengthLimit(const size_t) {} + virtual bool isTruncated() const { return (false); } + virtual void setTruncated() {} + virtual CompressMode getCompressMode() const { return (CASE_INSENSITIVE); } + virtual void setCompressMode(const CompressMode) {} + virtual void writeName(const Name& name, const bool = false) { + name.toWire(getBuffer()); + } +}; + +void +usage() { + cerr << "Usage: message_renderer_bench [-n iterations]" << endl; + exit (1); +} +} + +int +main(int argc, char* argv[]) { + int ch; + int iteration = 100000; + while ((ch = getopt(argc, argv, "n:")) != -1) { + switch (ch) { + case 'n': + iteration = atoi(optarg); + break; + case '?': + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc != 0) { + usage(); + } + + cout << "Parameters:" << endl; + cout << " Iterations: " << iteration << endl; + + typedef pair DataSpec; + vector spec_list; + spec_list.push_back(DataSpec(root_to_com_names, "(positive response)")); + spec_list.push_back(DataSpec(example_nxdomain_names, + "(NXDOMAIN response)")); + spec_list.push_back(DataSpec(example_servfail_names, + "(SERVFAIL response)")); + for (vector::const_iterator it = spec_list.begin(); + it != spec_list.end(); + ++it) { + vector names; + for (size_t i = 0; it->first[i] != NULL; ++i) { + names.push_back(Name(it->first[i])); + } + + typedef MessageRendererBenchMark + OldRendererBenchMark; + cout << "Benchmark for old MessageRenderer " << it->second << endl; + BenchMark(iteration, + OldRendererBenchMark(names)); + + typedef MessageRendererBenchMark + DumbRendererBenchMark; + cout << "Benchmark for dumb MessageRenderer " << it->second << endl; + BenchMark(iteration, + DumbRendererBenchMark(names)); + + typedef MessageRendererBenchMark RendererBenchMark; + cout << "Benchmark for new MessageRenderer " << it->second << endl; + BenchMark(iteration, RendererBenchMark(names)); + } + + return (0); +}