Skip to content

Commit f5799d1

Browse files
committed
1 parent 72f242f commit f5799d1

File tree

8 files changed

+141
-0
lines changed

8 files changed

+141
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
scoreboard objectives remove BenchStats
2+
scoreboard objectives add const dummy
3+
scoreboard objectives add BenchStats dummy
4+
scoreboard players set 10 const 10
5+
scoreboard players set 100 const 100
6+
scoreboard players set 50000 const 50000
7+
scoreboard players set 100000 const 100000
8+
#target should be < 50ms to prevent server from lagging and possibly crashing and > 0ms to allow the pack to work
9+
#larger values will cause scores to be worse because of recursion loop overhead
10+
#smaller values will be more noisy since less instances are being averaged over
11+
#suggested range is 10ms to 40ms
12+
#other programs running in the background may effect scores if they take up significant CPU time
13+
#this typically shows up as significant fluctuations in the numbers
14+
#can be set in game with a similar command as below
15+
scoreboard players set tickTarget BenchStats 25
16+
17+
scoreboard objectives setdisplay sidebar BenchStats
18+
function benchmark:reset
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#CALL FUNCTION/COMMAND TO BE BENCHMARKED HERE
2+
3+
4+
#increments #depth and calls next iteration of loop if #depth < #instances
5+
scoreboard players remove #instances BenchStats 1
6+
execute if score #instances BenchStats matches 1.. run function benchmark:instanceloop
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#needs to be biased to prevent early 0ms ticks from breaking the system before the initial 5s elapses
2+
data merge storage benchmark: {TickTimes:[]}
3+
scoreboard players set #depth BenchStats 0
4+
function benchmark:ticktime_init
5+
scoreboard players reset #depth BenchStats
6+
scoreboard players set #timeTotal BenchStats 100
7+
scoreboard players operation #timeTotal BenchStats *= tickTarget BenchStats
8+
9+
scoreboard players set #instances BenchStats 1
10+
data merge storage benchmark: {Instances:[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]}
11+
scoreboard players set #instTotal BenchStats 100
12+
13+
data merge storage benchmark: {10nsPerInst:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}
14+
scoreboard players set #10nsPITotal BenchStats 0
15+
16+
scoreboard players set #prev10nsPI BenchStats 0
17+
data merge storage benchmark: {TrendDiff:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}
18+
scoreboard players set #trendTotal BenchStats 0
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
scoreboard players add #depth BenchStats 1
2+
data modify storage benchmark: TickTimes prepend value 0
3+
execute store result storage benchmark: TickTimes[0] int 1 run scoreboard players get tickTarget BenchStats
4+
execute if score #depth BenchStats matches ..99 run function benchmark:ticktime_init
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#keep a running total of the number of instances in the last 5 seconds for fast averages and use in later calculations
2+
#the average is useful for approximating how many times the operation can be run within the target time (larger is better)
3+
#this is done early so we can retrieve the value later and prevent some recursion overhead
4+
execute store result score #lastInst BenchStats run data get storage benchmark: Instances[-1]
5+
data remove storage benchmark: Instances[-1]
6+
scoreboard players operation #instTotal BenchStats -= #lastInst BenchStats
7+
#execute store can't create new indexes in an array, so we need to create one before storing
8+
data modify storage benchmark: Instances prepend value 0
9+
execute store result storage benchmark: Instances[0] int 1 run scoreboard players get #instances BenchStats
10+
scoreboard players operation #instTotal BenchStats += #instances BenchStats
11+
#calculate the average of the last 5 seconds
12+
scoreboard players operation avgInstances BenchStats = #instTotal BenchStats
13+
scoreboard players operation avgInstances BenchStats /= 100 const
14+
15+
#using moving world border to determine real world tick times in ms
16+
#this is the bit that acts as the so called wall clock
17+
worldborder set 60000000
18+
worldborder set 59999000 1
19+
20+
#recursively calls instances of the function to be tested
21+
function benchmark:instanceloop
22+
23+
#get the time the tick took to finish
24+
execute store result score #borderSize BenchStats run worldborder get
25+
scoreboard players set #tickTime BenchStats 60000000
26+
scoreboard players operation #tickTime BenchStats -= #borderSize BenchStats
27+
28+
#keep a running total of the tick times in the last 5 seconds for use in later calculations
29+
execute store result score #lastTime BenchStats run data get storage benchmark: TickTimes[-1]
30+
data remove storage benchmark: TickTimes[-1]
31+
scoreboard players operation #timeTotal BenchStats -= #lastTime BenchStats
32+
#execute store can't create new indexes in an array, so we need to create one before storing
33+
data modify storage benchmark: TickTimes prepend value 0
34+
execute store result storage benchmark: TickTimes[0] int 1 run scoreboard players get #tickTime BenchStats
35+
scoreboard players operation #timeTotal BenchStats += #tickTime BenchStats
36+
37+
#calculate 10ns/instance, needed to calculate the step size to speed up benchmarking
38+
#attempting to use finer resolution, may overflow the scoreboard on multiplication
39+
scoreboard players operation #10nsPerInst BenchStats = #timeTotal BenchStats
40+
#scaled up to prevent too much precision loss since time/instance can be < 1ms and divide by 0 is bad
41+
scoreboard players operation #10nsPerInst BenchStats *= 100000 const
42+
scoreboard players operation #10nsPerInst BenchStats /= #instTotal BenchStats
43+
44+
#calculate and apply step size: #stepSize = (target-ticktime)/(2*time_per_instance)
45+
scoreboard players operation #stepSize BenchStats = tickTarget BenchStats
46+
scoreboard players operation #stepSize BenchStats -= #tickTime BenchStats
47+
#scaled up because time/instance had to be scaled up (100000/2)
48+
scoreboard players operation #stepSize BenchStats *= 50000 const
49+
scoreboard players operation #stepSize BenchStats /= #10nsPerInst BenchStats
50+
#restore instance number for comparison/math
51+
execute store result score #instances BenchStats run data get storage benchmark: Instances[0]
52+
scoreboard players operation #instances BenchStats += #stepSize BenchStats
53+
#prevent #instances from going below the minimum value of 1
54+
#this can happen in the case that the CPU was busy with another process and caused a spike in the time taken
55+
execute if score #instances BenchStats matches ..0 run scoreboard players set #instances BenchStats 1
56+
57+
#keep a running total of nsPerInst in the last 5 seconds for fast averages
58+
#the average is useful for approximating how long an operation took (lower is better)
59+
execute store result score #last10nsPI BenchStats run data get storage benchmark: 10nsPerInst[-1]
60+
data remove storage benchmark: 10nsPerInst[-1]
61+
scoreboard players operation #10nsPITotal BenchStats -= #last10nsPI BenchStats
62+
#execute store can't create new indexes in an array, so we need to create one before storing
63+
data modify storage benchmark: 10nsPerInst prepend value 0
64+
execute store result storage benchmark: 10nsPerInst[0] int 1 run scoreboard players get #10nsPerInst BenchStats
65+
scoreboard players operation #10nsPITotal BenchStats += #10nsPerInst BenchStats
66+
#calculate the average of the last 5 seconds
67+
scoreboard players operation avgNsPerInst BenchStats = #10nsPITotal BenchStats
68+
scoreboard players operation avgNsPerInst BenchStats /= 10 const
69+
70+
#calculate the trend of the time per instance of the past 5 seconds to display to the user
71+
#trend is an average of the last 5s in the difference between how long an instance took this tick vs the previous tick
72+
#this is useful for telling when the benchmark is stable/done (when it approaches 0)
73+
scoreboard players operation #trendDiff BenchStats = #10nsPerInst BenchStats
74+
scoreboard players operation #trendDiff BenchStats -= #prev10nsPI BenchStats
75+
scoreboard players operation #prev10nsPI BenchStats = #10nsPerInst BenchStats
76+
execute store result score #lastTrendDiff BenchStats run data get storage benchmark: TrendDiff[-1]
77+
data remove storage benchmark: TrendDiff[-1]
78+
scoreboard players operation #trendTotal BenchStats -= #lastTrendDiff BenchStats
79+
data modify storage benchmark: TrendDiff prepend value 0
80+
execute store result storage benchmark: TrendDiff[0] int 1 run scoreboard players get #trendDiff BenchStats
81+
scoreboard players operation #trendTotal BenchStats += #trendDiff BenchStats
82+
scoreboard players operation TPI_Trend BenchStats = #trendTotal BenchStats
83+
scoreboard players operation TPI_Trend BenchStats /= 100 const
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"values": ["benchmark:init_benchmark"]
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"values": ["benchmark:wallclock"]
3+
}

Benchmark/pack.mcmeta

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"pack": {
3+
"pack_format": 5,
4+
"description": "A simple function efficiency tester"
5+
}
6+
}

0 commit comments

Comments
 (0)