builtin_bench.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id$
  15. #include <sys/time.h>
  16. #include <iostream>
  17. #include <sstream>
  18. #include <dns/cpp/buffer.h>
  19. #include <dns/cpp/messagerenderer.h>
  20. #include <dns/cpp/name.h>
  21. #include <dns/cpp/rdata.h>
  22. #include <dns/cpp/rrclass.h>
  23. #include <dns/cpp/rrtype.h>
  24. #include <dns/cpp/rrttl.h>
  25. #include <dns/cpp/rrset.h>
  26. #include "builtin.h"
  27. using namespace std;
  28. using namespace isc::dns;
  29. using namespace isc::dns::rdata;
  30. static const int ITERATION = 100000;
  31. namespace {
  32. Name authors_name("authors.bind");
  33. inline double
  34. tv_sub(const struct timeval& t1, const struct timeval& t2)
  35. {
  36. struct timeval result;
  37. result.tv_sec = t1.tv_sec - t2.tv_sec;
  38. result.tv_usec = t1.tv_usec - t2.tv_usec;
  39. if (result.tv_usec < 0) {
  40. result.tv_usec += 1000000;
  41. result.tv_sec--;
  42. }
  43. return (result.tv_sec + result.tv_usec / 1000000.0);
  44. }
  45. inline RRsetPtr
  46. getNormalRRset()
  47. {
  48. RRsetPtr rrset = RRsetPtr(new RRset(authors_name, RRClass::CH(),
  49. RRType::TXT(), RRTTL(0)));
  50. rrset->addRdata(generic::TXT("Han Feng"));
  51. rrset->addRdata(generic::TXT("Kazunori Fujiwara"));
  52. rrset->addRdata(generic::TXT("Michael Graff"));
  53. rrset->addRdata(generic::TXT("Evan Hunt"));
  54. rrset->addRdata(generic::TXT("Jelte Jansen"));
  55. rrset->addRdata(generic::TXT("Jin Jian"));
  56. rrset->addRdata(generic::TXT("JINMEI Tatuya"));
  57. rrset->addRdata(generic::TXT("Naoki Kambe"));
  58. rrset->addRdata(generic::TXT("Shane Kerr"));
  59. rrset->addRdata(generic::TXT("Zhang Likun"));
  60. rrset->addRdata(generic::TXT("Jeremy C. Reed"));
  61. return (rrset);
  62. }
  63. void
  64. showResult(const struct timeval& tv_begin, const struct timeval& tv_end,
  65. int iteration, const char* description)
  66. {
  67. double diff = tv_sub(tv_end, tv_begin);
  68. cout << description << " " << iteration << " times in "
  69. << fixed << diff << "sec ("
  70. << static_cast<int>(iteration / diff) << "qps)" << endl;
  71. }
  72. }
  73. int
  74. main(int argc, char* argv[])
  75. {
  76. int iteration = ITERATION;
  77. if (argc > 1) {
  78. istringstream(argv[1]) >> dec >> iteration;
  79. }
  80. struct timeval tv_begin, tv_end;
  81. OutputBuffer buffer(512);
  82. MessageRenderer renderer(buffer);
  83. //
  84. // Benchmark for rendering an optimized pre-format RRset
  85. //
  86. gettimeofday(&tv_begin, NULL);
  87. for (int i = 0; i < iteration; ++i) {
  88. renderer.clear();
  89. renderer.skip(12);
  90. renderer.writeName(authors_name);
  91. RRsetPtr rrset_optimized = getBuiltinAuthors().getAnswer();
  92. rrset_optimized->toWire(renderer);
  93. }
  94. gettimeofday(&tv_end, NULL);
  95. showResult(tv_begin, tv_end, iteration, "Rendered optimized RRset");
  96. vector<unsigned char> data(buffer.getLength());
  97. memcpy(&data[0], buffer.getData(), buffer.getLength());
  98. //
  99. // Benchmark for rendering a general purpose RRset of the same content
  100. //
  101. RRsetPtr rrset_normal = getNormalRRset();
  102. gettimeofday(&tv_begin, NULL);
  103. for (int i = 0; i < iteration; ++i) {
  104. renderer.clear();
  105. renderer.skip(12);
  106. renderer.writeName(authors_name);
  107. rrset_normal->toWire(renderer);
  108. }
  109. gettimeofday(&tv_end, NULL);
  110. showResult(tv_begin, tv_end, iteration, "Rendered normal RRset");
  111. // Confirm the two sets of output are identical.
  112. if (data.size() != buffer.getLength() ||
  113. memcmp(&data[0], buffer.getData(), buffer.getLength())) {
  114. cerr << "Rendered data mismatch" << endl;
  115. return (1);
  116. }
  117. //
  118. // Benchmark for rendering a general purpose RRset of the same content
  119. //
  120. gettimeofday(&tv_begin, NULL);
  121. for (int i = 0; i < iteration; ++i) {
  122. renderer.clear();
  123. renderer.skip(12);
  124. renderer.writeName(authors_name);
  125. getNormalRRset()->toWire(renderer);
  126. }
  127. gettimeofday(&tv_end, NULL);
  128. showResult(tv_begin, tv_end, iteration,
  129. "Rendered normal RRset with fromText");
  130. // Confirm the two sets of output are identical.
  131. if (data.size() != buffer.getLength() ||
  132. memcmp(&data[0], buffer.getData(), buffer.getLength())) {
  133. cerr << "Rendered data mismatch" << endl;
  134. return (1);
  135. }
  136. return (0);
  137. }