benchmark.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright (C) 2012 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. #include <iostream>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "benchmark.h"
  18. using namespace std;
  19. uBenchmark::uBenchmark(uint32_t iterations, const std::string& dbname,
  20. bool sync /*= false*/, bool verbose /*= true*/,
  21. const std::string& host /* = "" */,
  22. const std::string& user /* = "" */,
  23. const std::string& pass /* = "" */)
  24. :Num_(iterations), Sync_(sync), Verbose_(verbose),
  25. Hostname_(host), User_(user), Passwd_(pass), DBName_(dbname)
  26. {
  27. memset(ts, 0, sizeof(ts));
  28. }
  29. void uBenchmark::usage() {
  30. cout << "This is a benchmark designed to measure expected performance" << endl;
  31. cout << "of several backends. This backend identifies itself as:" << endl;
  32. printInfo();
  33. cout << endl << "Possible command-line parameters:" << endl;
  34. cout << " -h - help (you are reading this)" << endl;
  35. cout << " -m hostname - specifies MySQL server to connect (MySQL backend only)" << endl;
  36. cout << " -u username - specifies MySQL user name (MySQL backend only)" << endl;
  37. cout << " -p password - specifies MySQL passwod (MySQL backend only)" << endl;
  38. cout << " -f name - database or filename (MySQL, SQLite and memfile)" << endl;
  39. cout << " -n integer - number of test repetitions (MySQL, SQLite and memfile)" << endl;
  40. cout << " -s yes|no - synchronous/asynchronous operation (MySQL, SQLite and memfile)" << endl;
  41. cout << " -v yes|no - verbose mode (MySQL, SQLite and memfile)" << endl;
  42. exit(EXIT_FAILURE);
  43. }
  44. bool uBenchmark::parseCmdline(int argc, char* const argv[]) {
  45. int ch;
  46. while ((ch = getopt(argc, argv, "hm:u:p:f:n:s:v:")) != -1) {
  47. switch (ch) {
  48. case 'h':
  49. usage();
  50. case 'm':
  51. Hostname_ = string(optarg);
  52. break;
  53. case 'u':
  54. User_ = string(optarg);
  55. break;
  56. case 'p':
  57. Passwd_ = string(optarg);
  58. break;
  59. case 'f':
  60. DBName_ = string(optarg);
  61. break;
  62. case 'n':
  63. Num_ = strtol(optarg, NULL, 10);
  64. if (Num_ <= 0) {
  65. cerr << "Failed to iterations (-n option)." << endl;
  66. usage();
  67. }
  68. break;
  69. case 's':
  70. if (!strcasecmp(optarg, "yes") || !strcmp(optarg,"1")) {
  71. Sync_ = true;
  72. } else {
  73. Sync_ = false;
  74. }
  75. break;
  76. case 'v':
  77. if (!strcasecmp(optarg, "yes") || !strcmp(optarg,"1")) {
  78. Verbose_ = true;
  79. } else {
  80. Verbose_ = false;
  81. }
  82. break;
  83. case ':':
  84. default:
  85. usage();
  86. }
  87. }
  88. return true;
  89. }
  90. void uBenchmark::failure(const char* operation) {
  91. cout << "Error during " << operation << endl;
  92. throw string(operation);
  93. }
  94. void uBenchmark::print_clock(const std::string& operation, uint32_t num,
  95. const struct timespec& before,
  96. const struct timespec& after) {
  97. long int tv_sec = after.tv_sec - before.tv_sec;
  98. long int tv_nsec = after.tv_nsec - before.tv_nsec;
  99. if (tv_nsec < 0) {
  100. tv_sec--;
  101. tv_nsec += 1000000000; // 10^9
  102. }
  103. double oneoper = (tv_nsec/1000 + tv_sec*1000000)/num;
  104. cout << operation << " repeated " << num << " times took "
  105. << tv_sec << " s, " << tv_nsec/1000 << " us, 1 operation took "
  106. << oneoper << "us (or " << (1000000/oneoper) << " oper/sec)" << endl;
  107. }
  108. int uBenchmark::run() {
  109. cout << "Starting test. Parameters: " << endl
  110. << "Number of iterations :" << Num_ << endl
  111. << "Sync/async :" << (Sync_?"sync":"async") << endl
  112. << "Verbose :" << (Verbose_?"verbose":"quiet") << endl
  113. << "Database name :" << DBName_ << endl
  114. << "MySQL hostname :" << Hostname_ << endl
  115. << "MySQL username :" << User_ << endl
  116. << "MySQL password :" << Passwd_ << endl << endl;
  117. srandom(time(NULL));
  118. try {
  119. connect();
  120. clock_gettime(CLOCK_REALTIME, &ts[0]);
  121. createLease4Test();
  122. clock_gettime(CLOCK_REALTIME, &ts[1]);
  123. searchLease4Test();
  124. clock_gettime(CLOCK_REALTIME, &ts[2]);
  125. updateLease4Test();
  126. clock_gettime(CLOCK_REALTIME, &ts[3]);
  127. deleteLease4Test();
  128. clock_gettime(CLOCK_REALTIME, &ts[4]);
  129. disconnect();
  130. } catch (const std::string& e) {
  131. cout << "Failed: " << e << endl;
  132. return (-1);
  133. }
  134. print_clock("Create leases4", Num_, ts[0], ts[1]);
  135. print_clock("Search leases4", Num_, ts[1], ts[2]);
  136. print_clock("Update leases4", Num_, ts[2], ts[3]);
  137. print_clock("Delete leases4", Num_, ts[3], ts[4]);
  138. return (0);
  139. }