Benchmark.C 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright (C) 2011 Emweb bvba, Kessel-Lo, Belgium.
  3. *
  4. * See the LICENSE file for terms of use.
  5. */
  6. #include <boost/test/unit_test.hpp>
  7. #include <Wt/Dbo/Dbo>
  8. #include <Wt/WDateTime>
  9. #include <Wt/Dbo/WtSqlTraits>
  10. #include "DboFixture.h"
  11. namespace dbo = Wt::Dbo;
  12. /*
  13. * Small benchmark inspired on:
  14. * http://www.codesynthesis.com/~boris/blog/2011/04/06/performance-odb-cxx-orm-vs-cs-orm/
  15. *
  16. * (We get about same performance for Sqlite3, but slower performance
  17. * for Postgres -- twice as slow, all because we do not use binary I/O
  18. * in the backend, and we pay the price for datetime parsing)
  19. */
  20. namespace Perf {
  21. class Post {
  22. public:
  23. long id;
  24. std::string text;
  25. Wt::WDateTime creation_date;
  26. Wt::WDateTime last_change_date;
  27. int counter[10];
  28. template<class Action>
  29. void persist(Action& a)
  30. {
  31. /*
  32. * Concatenating this string becomes a bottleneck, persist()
  33. * is called alot...
  34. */
  35. static const char *counterFields[]
  36. = { "counter1", "counter2", "counter3", "counter4", "counter5",
  37. "counter6", "counter7", "counter8", "counter9", "counter10" };
  38. dbo::id(a, id, "id");
  39. dbo::field(a, text, "text");
  40. dbo::field(a, creation_date, "creation_date");
  41. dbo::field(a, last_change_date, "last_change_date");
  42. for (int i = 0; i < 10; ++i)
  43. dbo::field(a, counter[i], counterFields[i]);
  44. }
  45. };
  46. }
  47. struct DboBenchmarkFixture : DboFixtureBase
  48. {
  49. DboBenchmarkFixture() :
  50. DboFixtureBase(false)
  51. {
  52. session_->mapClass<Perf::Post>("post");
  53. try {
  54. session_->dropTables();
  55. } catch (...) {
  56. }
  57. session_->createTables();
  58. }
  59. };
  60. namespace Wt {
  61. namespace Dbo {
  62. /*
  63. * Customize the mapping: disable version field and surrogate ID
  64. */
  65. template<>
  66. struct dbo_traits<Perf::Post> : public dbo_default_traits {
  67. typedef long IdType;
  68. static const char *surrogateIdField() { return 0; }
  69. static const char *versionField() { return 0; }
  70. static IdType invalidId() { return -1; }
  71. };
  72. }
  73. }
  74. BOOST_AUTO_TEST_CASE( performance_test )
  75. {
  76. DboBenchmarkFixture f;
  77. dbo::Session &session = *(f.session_);
  78. dbo::Transaction t(session);
  79. const unsigned total_objects = 10000;
  80. const std::string text = "some text?";
  81. std::cerr << "Loading " << total_objects << " objects in database."
  82. << std::endl;
  83. for (unsigned i = 0; i < total_objects; ++i) {
  84. Perf::Post *p = new Perf::Post();
  85. p->id = i;
  86. p->text = text;
  87. p->creation_date = Wt::WDateTime::currentDateTime().addSecs(-i * 60 * 60);
  88. p->last_change_date = Wt::WDateTime::currentDateTime();
  89. for (unsigned k = 0; k < 10; ++k)
  90. p->counter[k] = i + k + 1;
  91. session.add(p);
  92. }
  93. t.commit();
  94. std::cerr << "Measuring selection ..." << std::endl;
  95. boost::posix_time::ptime start
  96. = boost::posix_time::microsec_clock::local_time();
  97. const unsigned times = 100;
  98. for (unsigned i = 0; i < times; ++i) {
  99. dbo::Transaction t(session);
  100. dbo::ptr<Perf::Post> p;
  101. for (unsigned long i = 0; i < 500; ++i) {
  102. unsigned long id = std::rand() % total_objects;
  103. p = session.load<Perf::Post>(id);
  104. }
  105. t.commit();
  106. }
  107. boost::posix_time::ptime
  108. end = boost::posix_time::microsec_clock::local_time();
  109. boost::posix_time::time_duration d = end - start;
  110. std::cerr << "Took: " << (double)d.total_microseconds() / 1000 / times
  111. << " ms per 500 selects." << std::endl;
  112. //session.dropTables();
  113. }