1
0

init.lua 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. -- Safeguard against too much optimization. This way the results cannot be optimized
  2. -- away, but they can be garbage collected (due to __mode = "k").
  3. _G._bench_content_ids_data = setmetatable({}, {__mode = "k"})
  4. local function bench_name2content()
  5. local t = {}
  6. _G._bench_content_ids_data[t] = true
  7. local get_content_id = core.get_content_id
  8. local start = core.get_us_time()
  9. for i = 1, 200 do
  10. for name in pairs(core.registered_nodes) do
  11. t[#t + 1] = get_content_id(name)
  12. end
  13. end
  14. local finish = core.get_us_time()
  15. return (finish - start) / 1000
  16. end
  17. local function bench_content2name()
  18. local t = {}
  19. _G._bench_content_ids_data[t] = true
  20. -- Try to estimate the highest content ID that's used
  21. -- (not accurate but good enough for this test)
  22. local n = 0
  23. for _ in pairs(core.registered_nodes) do
  24. n = n + 1
  25. end
  26. local get_name_from_content_id = core.get_name_from_content_id
  27. local start = core.get_us_time()
  28. for i = 1, 200 do
  29. for j = 0, n do
  30. t[#t + 1] = get_name_from_content_id(j)
  31. end
  32. end
  33. local finish = core.get_us_time()
  34. return (finish - start) / 1000
  35. end
  36. core.register_chatcommand("bench_name2content", {
  37. params = "",
  38. description = "Benchmark: Conversion from node names to content IDs",
  39. func = function(name, param)
  40. core.chat_send_player(name, "Benchmarking core.get_content_id. Warming up ...")
  41. bench_name2content()
  42. core.chat_send_player(name, "Warming up finished, now benchmarking ...")
  43. local time = bench_name2content()
  44. return true, ("Time: %.2f ms"):format(time)
  45. end,
  46. })
  47. core.register_chatcommand("bench_content2name", {
  48. params = "",
  49. description = "Benchmark: Conversion from content IDs to node names",
  50. func = function(name, param)
  51. core.chat_send_player(name, "Benchmarking core.get_name_from_content_id. Warming up ...")
  52. bench_content2name()
  53. core.chat_send_player(name, "Warming up finished, now benchmarking ...")
  54. local time = bench_content2name()
  55. return true, ("Time: %.2f ms"):format(time)
  56. end,
  57. })
  58. local function get_positions_cube(ppos)
  59. local pos_list = {}
  60. local i = 1
  61. for x=2,100 do
  62. for y=2,100 do
  63. for z=2,100 do
  64. pos_list[i] = ppos:offset(x, y, z)
  65. i = i + 1
  66. end
  67. end
  68. end
  69. return pos_list
  70. end
  71. core.register_chatcommand("bench_bulk_set_node", {
  72. params = "",
  73. description = "Benchmark: Bulk-set 99×99×99 stone nodes",
  74. func = function(name, param)
  75. local player = core.get_player_by_name(name)
  76. if not player then
  77. return false, "No player."
  78. end
  79. local pos_list = get_positions_cube(player:get_pos())
  80. core.chat_send_player(name, "Benchmarking core.bulk_set_node. Warming up ...")
  81. -- warm up with stone to prevent having different callbacks
  82. -- due to different node topology
  83. core.bulk_set_node(pos_list, {name = "mapgen_stone"})
  84. core.chat_send_player(name, "Warming up finished, now benchmarking ...")
  85. local start_time = core.get_us_time()
  86. for i=1,#pos_list do
  87. core.set_node(pos_list[i], {name = "mapgen_stone"})
  88. end
  89. local middle_time = core.get_us_time()
  90. core.bulk_set_node(pos_list, {name = "mapgen_stone"})
  91. local end_time = core.get_us_time()
  92. local msg = string.format("Benchmark results: core.set_node loop: %.2f ms; core.bulk_set_node: %.2f ms",
  93. ((middle_time - start_time)) / 1000,
  94. ((end_time - middle_time)) / 1000
  95. )
  96. return true, msg
  97. end,
  98. })
  99. core.register_chatcommand("bench_bulk_get_node", {
  100. params = "",
  101. description = "Benchmark: Bulk-get 99×99×99 nodes",
  102. func = function(name, param)
  103. local player = core.get_player_by_name(name)
  104. if not player then
  105. return false, "No player."
  106. end
  107. local pos_list = get_positions_cube(player:get_pos())
  108. local function bench()
  109. local start_time = core.get_us_time()
  110. for i=1,#pos_list do
  111. local n = core.get_node(pos_list[i])
  112. -- Make sure the name lookup is never optimized away.
  113. -- Table allocation might still be omitted. But only accessing
  114. -- the name of a node is a common pattern anyways.
  115. if n.name == "benchmarks:nonexistent_node" then
  116. error("should never happen")
  117. end
  118. end
  119. return core.get_us_time() - start_time
  120. end
  121. core.chat_send_player(name, "Benchmarking core.get_node. Warming up ...")
  122. bench()
  123. core.chat_send_player(name, "Warming up finished, now benchmarking ...")
  124. local result_us = bench()
  125. local msg = string.format("Benchmark results: core.get_node loop 1: %.2f ms",
  126. result_us / 1000)
  127. return true, msg
  128. end,
  129. })
  130. core.register_chatcommand("bench_bulk_swap_node", {
  131. params = "",
  132. description = "Benchmark: Bulk-swap 99×99×99 stone nodes",
  133. func = function(name, param)
  134. local player = core.get_player_by_name(name)
  135. if not player then
  136. return false, "No player."
  137. end
  138. local pos_list = get_positions_cube(player:get_pos())
  139. core.chat_send_player(name, "Benchmarking core.bulk_swap_node. Warming up ...")
  140. -- warm up because first execution otherwise becomes
  141. -- significantly slower
  142. core.bulk_swap_node(pos_list, {name = "mapgen_stone"})
  143. core.chat_send_player(name, "Warming up finished, now benchmarking ...")
  144. local start_time = core.get_us_time()
  145. for i=1,#pos_list do
  146. core.swap_node(pos_list[i], {name = "mapgen_stone"})
  147. end
  148. local middle_time = core.get_us_time()
  149. core.bulk_swap_node(pos_list, {name = "mapgen_stone"})
  150. local end_time = core.get_us_time()
  151. local msg = string.format("Benchmark results: core.swap_node loop: %.2f ms; core.bulk_swap_node: %.2f ms",
  152. ((middle_time - start_time)) / 1000,
  153. ((end_time - middle_time)) / 1000
  154. )
  155. return true, msg
  156. end,
  157. })