BenchmarkDb.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import os
  2. import json
  3. import contextlib
  4. import time
  5. from Plugin import PluginManager
  6. from Config import config
  7. @PluginManager.registerTo("Actions")
  8. class ActionsPlugin:
  9. def getBenchmarkTests(self, online=False):
  10. tests = super().getBenchmarkTests(online)
  11. tests.extend([
  12. {"func": self.testDbConnect, "num": 10, "time_standard": 0.27},
  13. {"func": self.testDbInsert, "num": 10, "time_standard": 0.91},
  14. {"func": self.testDbInsertMultiuser, "num": 1, "time_standard": 0.57},
  15. {"func": self.testDbQueryIndexed, "num": 1000, "time_standard": 0.84},
  16. {"func": self.testDbQueryNotIndexed, "num": 1000, "time_standard": 1.30}
  17. ])
  18. return tests
  19. @contextlib.contextmanager
  20. def getTestDb(self):
  21. from Db import Db
  22. path = "%s/benchmark.db" % config.data_dir
  23. if os.path.isfile(path):
  24. os.unlink(path)
  25. schema = {
  26. "db_name": "TestDb",
  27. "db_file": path,
  28. "maps": {
  29. ".*": {
  30. "to_table": {
  31. "test": "test"
  32. }
  33. }
  34. },
  35. "tables": {
  36. "test": {
  37. "cols": [
  38. ["test_id", "INTEGER"],
  39. ["title", "TEXT"],
  40. ["json_id", "INTEGER REFERENCES json (json_id)"]
  41. ],
  42. "indexes": ["CREATE UNIQUE INDEX test_key ON test(test_id, json_id)"],
  43. "schema_changed": 1426195822
  44. }
  45. }
  46. }
  47. db = Db.Db(schema, path)
  48. yield db
  49. db.close()
  50. if os.path.isfile(path):
  51. os.unlink(path)
  52. def testDbConnect(self, num_run=1):
  53. import sqlite3
  54. for i in range(num_run):
  55. with self.getTestDb() as db:
  56. db.checkTables()
  57. yield "."
  58. yield "(SQLite version: %s, API: %s)" % (sqlite3.sqlite_version, sqlite3.version)
  59. def testDbInsert(self, num_run=1):
  60. yield "x 1000 lines "
  61. for u in range(num_run):
  62. with self.getTestDb() as db:
  63. db.checkTables()
  64. data = {"test": []}
  65. for i in range(1000): # 1000 line of data
  66. data["test"].append({"test_id": i, "title": "Testdata for %s message %s" % (u, i)})
  67. json.dump(data, open("%s/test_%s.json" % (config.data_dir, u), "w"))
  68. db.updateJson("%s/test_%s.json" % (config.data_dir, u))
  69. os.unlink("%s/test_%s.json" % (config.data_dir, u))
  70. assert db.execute("SELECT COUNT(*) FROM test").fetchone()[0] == 1000
  71. yield "."
  72. def fillTestDb(self, db):
  73. db.checkTables()
  74. cur = db.getCursor()
  75. cur.logging = False
  76. for u in range(100, 200): # 100 user
  77. data = {"test": []}
  78. for i in range(100): # 1000 line of data
  79. data["test"].append({"test_id": i, "title": "Testdata for %s message %s" % (u, i)})
  80. json.dump(data, open("%s/test_%s.json" % (config.data_dir, u), "w"))
  81. db.updateJson("%s/test_%s.json" % (config.data_dir, u), cur=cur)
  82. os.unlink("%s/test_%s.json" % (config.data_dir, u))
  83. if u % 10 == 0:
  84. yield "."
  85. def testDbInsertMultiuser(self, num_run=1):
  86. yield "x 100 users x 100 lines "
  87. for u in range(num_run):
  88. with self.getTestDb() as db:
  89. for progress in self.fillTestDb(db):
  90. yield progress
  91. num_rows = db.execute("SELECT COUNT(*) FROM test").fetchone()[0]
  92. assert num_rows == 10000, "%s != 10000" % num_rows
  93. def testDbQueryIndexed(self, num_run=1):
  94. s = time.time()
  95. with self.getTestDb() as db:
  96. for progress in self.fillTestDb(db):
  97. pass
  98. yield " (Db warmup done in %.3fs) " % (time.time() - s)
  99. found_total = 0
  100. for i in range(num_run): # 1000x by test_id
  101. found = 0
  102. res = db.execute("SELECT * FROM test WHERE test_id = %s" % (i % 100))
  103. for row in res:
  104. found_total += 1
  105. found += 1
  106. del(res)
  107. yield "."
  108. assert found == 100, "%s != 100 (i: %s)" % (found, i)
  109. yield "Found: %s" % found_total
  110. def testDbQueryNotIndexed(self, num_run=1):
  111. s = time.time()
  112. with self.getTestDb() as db:
  113. for progress in self.fillTestDb(db):
  114. pass
  115. yield " (Db warmup done in %.3fs) " % (time.time() - s)
  116. found_total = 0
  117. for i in range(num_run): # 1000x by test_id
  118. found = 0
  119. res = db.execute("SELECT * FROM test WHERE json_id = %s" % i)
  120. for row in res:
  121. found_total += 1
  122. found += 1
  123. yield "."
  124. del(res)
  125. if i == 0 or i > 100:
  126. assert found == 0, "%s != 0 (i: %s)" % (found, i)
  127. else:
  128. assert found == 100, "%s != 100 (i: %s)" % (found, i)
  129. yield "Found: %s" % found_total