From: JINMEI Tatuya Date: Thu, 30 Aug 2012 00:23:11 +0000 (-0700) Subject: [2098] added a simple micro benchmark test for rendering TreeNodeRRsets. X-Git-Tag: trac2351_base~91^2~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b4bbfceb45dbfa2f7e55936d9601e642ea3f5583;p=thirdparty%2Fkea.git [2098] added a simple micro benchmark test for rendering TreeNodeRRsets. --- diff --git a/src/lib/datasrc/memory/benchmarks/Makefile.am b/src/lib/datasrc/memory/benchmarks/Makefile.am index e86c1944eb..f4ae3eefc5 100644 --- a/src/lib/datasrc/memory/benchmarks/Makefile.am +++ b/src/lib/datasrc/memory/benchmarks/Makefile.am @@ -9,9 +9,12 @@ endif CLEANFILES = *.gcno *.gcda -noinst_PROGRAMS = rdata_reader_bench +noinst_PROGRAMS = rdata_reader_bench rrset_render_bench rdata_reader_bench_SOURCES = rdata_reader_bench.cc - rdata_reader_bench_LDADD = $(top_builddir)/src/lib/datasrc/memory/libdatasrc_memory.la rdata_reader_bench_LDADD += $(top_builddir)/src/lib/dns/libb10-dns++.la + +rrset_render_bench_SOURCES = rrset_render_bench.cc +rrset_render_bench_LDADD = $(top_builddir)/src/lib/datasrc/memory/libdatasrc_memory.la +rrset_render_bench_LDADD += $(top_builddir)/src/lib/dns/libb10-dns++.la diff --git a/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc b/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc new file mode 100644 index 0000000000..c5cdef6675 --- /dev/null +++ b/src/lib/datasrc/memory/benchmarks/rrset_render_bench.cc @@ -0,0 +1,246 @@ +// 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 +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +using std::vector; +using namespace isc::bench; +using namespace isc::datasrc::memory; +using namespace isc::dns; + +namespace { +// A simple benchmark just repeating rendering a given set of RRsets. +class RRsetRenderBenchMark { +public: + RRsetRenderBenchMark(const vector& rrsets, + MessageRenderer& renderer) : + rrsets_(rrsets), renderer_(renderer) + {} + unsigned int run() { + renderer_.clear(); + vector::const_iterator it; + const vector::const_iterator it_end = rrsets_.end(); + for (it = rrsets_.begin(); it != it_end; ++it) { + (*it)->toWire(renderer_); + } + return (1); + } +private: + const vector& rrsets_; + MessageRenderer& renderer_; +}; + +// Builtin benchmark data. This is a list of RDATA (of RRs) in a response +// from a root server for the query for "www.example.com" (as of this +// implementation). We use a real world example to make the case practical. +const char* const delegation_rrsets_txt = + // AUTHORITY SECTION (NS) + "com. 172800 IN NS a.gtld-servers.net.\n" + "com. 172800 IN NS b.gtld-servers.net.\n" + "com. 172800 IN NS c.gtld-servers.net.\n" + "com. 172800 IN NS d.gtld-servers.net.\n" + "com. 172800 IN NS e.gtld-servers.net.\n" + "com. 172800 IN NS f.gtld-servers.net.\n" + "com. 172800 IN NS g.gtld-servers.net.\n" + "com. 172800 IN NS h.gtld-servers.net.\n" + "com. 172800 IN NS i.gtld-servers.net.\n" + "com. 172800 IN NS j.gtld-servers.net.\n" + "com. 172800 IN NS k.gtld-servers.net.\n" + "com. 172800 IN NS l.gtld-servers.net.\n" + "com. 172800 IN NS m.gtld-servers.net.\n" + // AUTHORITY SECTION (DS) + "com. 86400 IN DS 30909 8 2 " + "E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766\n" + // AUTHORITY SECTION (RRSIG for DS) + "com. 86400 IN RRSIG DS 8 1 86400 20120822000000 20120814230000 50398 . " + "lcIpLRq4s91Fh1FihDXiDvVMMRqgy2jjlpiP4Y6sSjIrLue6Boi7xraj" + "Ouka34ubpl4KuIcopWe99LI/7Npvq0MYr9DaqfnX9dTW6Vc2C7/hKSsz" + "POYjraZZA3SCApgfNVzq+AscYlShi56f1vm7DQWw1eh1wHLdatidrQwNyDo=\n" + // ADDITIONAL SECTION + "a.gtld-servers.net. 172800 IN A 192.5.6.30\n" + "b.gtld-servers.net. 172800 IN A 192.33.14.30\n" + "c.gtld-servers.net. 172800 IN A 192.26.92.30\n" + "d.gtld-servers.net. 172800 IN A 192.31.80.30\n" + "e.gtld-servers.net. 172800 IN A 192.12.94.30\n" + "f.gtld-servers.net. 172800 IN A 192.35.51.30\n" + "g.gtld-servers.net. 172800 IN A 192.42.93.30\n" + "h.gtld-servers.net. 172800 IN A 192.54.112.30\n" + "i.gtld-servers.net. 172800 IN A 192.43.172.30\n" + "j.gtld-servers.net. 172800 IN A 192.48.79.30\n" + "k.gtld-servers.net. 172800 IN A 192.52.178.30\n" + "l.gtld-servers.net. 172800 IN A 192.41.162.30\n" + "m.gtld-servers.net. 172800 IN A 192.55.83.30\n" + "a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30\n" + "b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30"; + +// Likewise, it's a response from a root server for www.example.notexistent. +// An example that involves a few more RRSIGs. +const char* const nxdomain_rrsets_txt = + // AUTHORITY SECTION (NS) + ". 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2012082901 1800 900 604800 86400\n" + ". 86400 IN RRSIG SOA 8 0 86400 20120905000000 20120828230000 50398 . Wj6NgkA2TyJug9XfWYG/Cjh4d1JI99/Dv9S1TClbrhLdeMI4s9BEcBSA xdlPJN6L4uaupcYeEyRWGx3p0iq7VWFyjL4xy/+jXpUoHCgj0NlWa6eu C2litcnfcumTI97XJ5iod3ET+6vWnhwZQHDnz1fj4FuS8PPEJJ+Oy3M5 mcM=\n" + ". 86400 IN NSEC ac. NS SOA RRSIG NSEC DNSKEY\n" + ". 86400 IN RRSIG NSEC 8 0 86400 20120905000000 20120828230000 50398 . f8FEG1HzQtn/shZCdDgkB7TIpHAmH2hGlp5RubczukzD8XI3EGMVNoaf 2cUNPLpyhoBQkO1Rz+hANzI6Jkqq8PzhiQnLcW+y2Wl/BU2SaBQ2Otb2 5+VOOXux1veKaCZsRRU1VJnTUYguDayAgcS7BtB/rc7ez4nokkK98MA9 zcw=\n" + "no. 86400 IN NSEC np. NS RRSIG NSEC\n" + "no. 86400 IN RRSIG NSEC 8 1 86400 20120905000000 20120828230000 50398 . Z/E4hb6MMSpueGGjGoCWwnN2uKsQf88HPS1gbwVHBEhR+5eSn0BGqExs fQsjYL47SF/6pwMXjzmXCt8NPXXf9ImY/93GUuFL6j5OuL2MDIxt24MS u6hfxxiYTn+zF0dM8cn+UK5n1VEBB5JVJXf7FOr3OmaRLMD33Gl6yZJ/ l1E="; + +void +usage() { + std::cerr << "Usage: rrset_render_bench [-n iterations]" << std::endl; + exit (1); +} + +// Helper callback for masterLoad() used in main() to build test data. +void +setRRset(vector* rrsets, ConstRRsetPtr rrset) { + rrsets->push_back(rrset); +} + +void +buildZone(isc::util::MemorySegmentLocal& mem_sgmt, + ZoneData* zone_data, const vector& rrsets, + vector& rrsets_build) +{ + RdataEncoder encoder; + + for (vector::const_iterator it = rrsets.begin(); + it != rrsets.end(); + ++it) + { + ConstRRsetPtr rrset = *it; + ZoneNode* node; + zone_data->insertName(mem_sgmt, rrset->getName(), &node); + + // For simplicity, we assume that if the current RRset has a next + // one that is of type RRSIG, that RRSIG should be associated with + // the current RRset (which should be the case for our test data). + ConstRRsetPtr sig_rrset; + if ((it + 1) != rrsets.end() && + (*(it + 1))->getType() == RRType::RRSIG()) { + sig_rrset = *(++it); + } + RdataSet* rdataset = + RdataSet::create(mem_sgmt, encoder, rrset, sig_rrset); + rdataset->next = node->getData(); + node->setData(rdataset); + + rrsets_build.push_back( + ConstRRsetPtr(new TreeNodeRRset(rrset->getClass(), node, rdataset, + true))); + } +} +} + +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; + default: + usage(); + } + } + argc -= optind; + argv += optind; + if (argc != 0) { + usage(); + } + + // Build test data. rrsets will consist of a list of RRsets corresponding + // to the text defined above. + vector delegation_rrsets; + std::stringstream rrsets_stream(delegation_rrsets_txt); + masterLoad(rrsets_stream, Name::ROOT_NAME(), RRClass::IN(), + boost::bind(setRRset, &delegation_rrsets, _1)); + + vector nxdomain_rrsets; + std::stringstream rrsets_stream2(nxdomain_rrsets_txt); + masterLoad(rrsets_stream2, Name::ROOT_NAME(), RRClass::IN(), + boost::bind(setRRset, &nxdomain_rrsets, _1)); + + // Build in-memory zone using RRsets constructed above, storing + // the same set of RRsets as TreeNodeRRsets in separate vectors. + // This code below is not 100% exception safe (for simplicity), but at + // least it shouldn't leak memory in normal cases. + isc::util::MemorySegmentLocal mem_sgmt; + ZoneData* zone_data = ZoneData::create(mem_sgmt, Name::ROOT_NAME()); + vector delegation_treenode_rrsets; + buildZone(mem_sgmt, zone_data, delegation_rrsets, + delegation_treenode_rrsets); + vector nxdomain_treenode_rrsets; + buildZone(mem_sgmt, zone_data, nxdomain_rrsets, + nxdomain_treenode_rrsets); + + // The benchmark test uses a message renderer. Create it now and keep + // using it throughout the test. + isc::util::OutputBuffer buffer(4096); // 4096 should be sufficiently large + MessageRenderer renderer; + renderer.setBuffer(&buffer); + + std::cout << "Benchmark for rendering basic RRsets (delegation)" + << std::endl; + BenchMark(iteration, + RRsetRenderBenchMark(delegation_rrsets, + renderer)); + + std::cout << "Benchmark for rendering tree node RRsets (delegation)" + << std::endl; + BenchMark(iteration, + RRsetRenderBenchMark( + delegation_treenode_rrsets, renderer)); + + std::cout << "Benchmark for rendering basic RRsets (nxdomain)" + << std::endl; + BenchMark(iteration, + RRsetRenderBenchMark(nxdomain_rrsets, + renderer)); + + std::cout << "Benchmark for rendering tree node RRsets (nxdomain)" + << std::endl; + BenchMark(iteration, + RRsetRenderBenchMark( + nxdomain_treenode_rrsets, renderer)); + + // Cleanup, and memory leak check + ZoneData::destroy(mem_sgmt, zone_data, RRClass::IN()); + assert(mem_sgmt.allMemoryDeallocated()); + + return (0); +}