66
77local clock = os.clock
88local floor = math.floor
9- local sort = table.sort
10- local max = math.max
11- local min = math.min
9+ local sort = table.sort
10+ local max = math.max
11+ local min = math.min
1212
1313local function percentile (sorted : { number }, p : number ): number
1414 local idx = floor (# sorted * p / 100 + 0.5 )
1818local function fmtNum (n : number ): string
1919 local s = tostring (floor (n ))
2020 local len = # s
21- if len <= 3 then return s end
21+ if len <= 3 then
22+ return s
23+ end
2224 local parts = {}
2325 local rem = len % 3
24- if rem > 0 then table.insert (parts , s :sub (1 , rem )) end
26+ if rem > 0 then
27+ table.insert (parts , s :sub (1 , rem ))
28+ end
2529 for i = rem + 1 , len , 3 do
2630 table.insert (parts , s :sub (i , i + 2 ))
2731 end
2832 return table.concat (parts , "," )
2933end
3034
3135local function fmtBytes (n : number ): string
32- if n < 1024 then return `{n }B` end
33- if n < 1048576 then return `{floor (n / 1024 * 10 + 0.5 ) / 10 }KB` end
36+ if n < 1024 then
37+ return `{n }B`
38+ end
39+ if n < 1048576 then
40+ return `{floor (n / 1024 * 10 + 0.5 ) / 10 }KB`
41+ end
3442 return `{floor (n / 1048576 * 100 + 0.5 ) / 100 }MB`
3543end
3644
3745local function fmtTime (us : number ): string
38- if us < 1 then return `{floor (us * 1000 + 0.5 )}ns` end
39- if us < 1000 then return `{floor (us * 10 + 0.5 ) / 10 }µs` end
46+ if us < 1 then
47+ return `{floor (us * 1000 + 0.5 )}ns`
48+ end
49+ if us < 1000 then
50+ return `{floor (us * 10 + 0.5 ) / 10 }µs`
51+ end
4052 return `{floor (us / 1000 * 10 + 0.5 ) / 10 }ms`
4153end
4254
4557local Harness = {}
4658
4759function Harness .header (title : string ): ()
48- print ("╔══════════════════════════════════════════════════════════════╗" )
60+ print (
61+ "╔══════════════════════════════════════════════════════════════╗"
62+ )
4963 print (`║ {title }{string.rep (" " , 60 - # title - 2 )}║` )
50- print ("╚══════════════════════════════════════════════════════════════╝" )
64+ print (
65+ "╚══════════════════════════════════════════════════════════════╝"
66+ )
5167end
5268
5369function Harness .section (title : string ): ()
6379 Runs the function for warmup, then times N iterations.
6480 Returns ops/sec and mean time in microseconds.
6581]]
66- function Harness .benchEncode (
67- label : string ,
68- iterations : number ,
69- fn : () -> ()
70- ): ()
82+ function Harness .benchEncode (label : string , iterations : number , fn : () -> ()): ()
7183 -- Warmup
7284 for _ = 1 , min (1000 , iterations // 10 ) do
7385 fn ()
@@ -84,18 +96,16 @@ function Harness.benchEncode(
8496 local meanUs = elapsed / iterations * 1e6
8597
8698 print (` │ {label }` )
87- print (` │ {fmtNum (floor (opsPerSec ))} ops/sec {fmtTime (meanUs )}/op ({fmtNum (iterations )} iterations)` )
99+ print (
100+ ` │ {fmtNum (floor (opsPerSec ))} ops/sec {fmtTime (meanUs )}/op ({fmtNum (iterations )} iterations)`
101+ )
88102end
89103
90104--[[
91105 Measures wire size for a codec + value pair.
92106 Writes once and reports exact byte count.
93107]]
94- function Harness .benchWireSize (
95- label : string ,
96- codec : any ,
97- value : any
98- ): number
108+ function Harness .benchWireSize (label : string , codec : any , value : any ): number
99109 local Channel = require (script .Parent .Parent .internal .Channel )
100110 local ch = Channel .create ()
101111 codec .write (ch , value )
108118--[[
109119 Measures delta savings: first write vs unchanged second write.
110120]]
111- function Harness .benchDelta (
112- label : string ,
113- codec : any ,
114- value : any
115- ): ()
121+ function Harness .benchDelta (label : string , codec : any , value : any ): ()
116122 local Channel = require (script .Parent .Parent .internal .Channel )
117123 local ch = Channel .create ()
118124
@@ -141,19 +147,16 @@ function Harness.benchDelta(
141147 local savings = floor ((1 - unchangedBytes / fullBytes ) * 100 + 0.5 )
142148
143149 print (` │ {label }` )
144- print (` │ full={fullBytes }B unchanged={unchangedBytes }B changed={changedBytes }B savings={savings }%` )
150+ print (
151+ ` │ full={fullBytes }B unchanged={unchangedBytes }B changed={changedBytes }B savings={savings }%`
152+ )
145153end
146154
147155--[[
148156 Measures full round-trip: encode + decode for a codec.
149157 Reports encode time, decode time, and total.
150158]]
151- function Harness .benchRoundTrip (
152- label : string ,
153- iterations : number ,
154- codec : any ,
155- value : any
156- ): ()
159+ function Harness .benchRoundTrip (label : string , iterations : number , codec : any , value : any ): ()
157160 local Channel = require (script .Parent .Parent .internal .Channel )
158161 local ch = Channel .create ()
159162
@@ -192,7 +195,11 @@ function Harness.benchRoundTrip(
192195 local totalUs = encUs + decUs
193196
194197 print (` │ {label } ({written }B)` )
195- print (` │ encode={fmtTime (encUs )} decode={fmtTime (decUs )} total={fmtTime (totalUs )} {fmtNum (floor (iterations / (encodeTime + decodeTime )))} round-trips/sec` )
198+ print (
199+ ` │ encode={fmtTime (encUs )} decode={fmtTime (decUs )} total={fmtTime (totalUs )} {fmtNum (
200+ floor (iterations / (encodeTime + decodeTime ))
201+ )} round-trips/sec`
202+ )
196203end
197204
198205--[[
@@ -245,10 +252,10 @@ function Harness.benchNetwork(
245252 end
246253
247254 local fpsMed = floor (percentile (fpsData , 50 ) * 10 + 0.5 ) / 10
248- local fpsP1 = floor (percentile (fpsData , 1 ) * 10 + 0.5 ) / 10
249- local kMed = floor (percentile (kbpsData , 50 ) * 10 + 0.5 ) / 10
250- local kP95 = floor (percentile (kbpsData , 95 ) * 10 + 0.5 ) / 10
251- local kP99 = floor (percentile (kbpsData , 99 ) * 10 + 0.5 ) / 10
255+ local fpsP1 = floor (percentile (fpsData , 1 ) * 10 + 0.5 ) / 10
256+ local kMed = floor (percentile (kbpsData , 50 ) * 10 + 0.5 ) / 10
257+ local kP95 = floor (percentile (kbpsData , 95 ) * 10 + 0.5 ) / 10
258+ local kP99 = floor (percentile (kbpsData , 99 ) * 10 + 0.5 ) / 10
252259
253260 print (` │ {label }` )
254261 print (` │ FPS: median={fpsMed } p1={fpsP1 }` )
@@ -280,11 +287,11 @@ function Harness.benchComparison(
280287 end
281288 task.wait (2 )
282289
283- local fpsData : { number } = {}
290+ local fpsData : { number } = {}
284291 local kbpsData : { number } = {}
285- local frames = 0
292+ local frames = 0
286293 local elapsed = 0
287- local sent = 0
294+ local sent = 0
288295
289296 local conn = RunService .Heartbeat :Connect (function (dt : number ): ()
290297 frames += 1
@@ -310,7 +317,9 @@ function Harness.benchComparison(
310317
311318 sort (kbpsData )
312319 -- FPS sorted descending: P0 = best, P100 = worst
313- sort (fpsData , function (a : number , b : number ): boolean return a > b end )
320+ sort (fpsData , function (a : number , b : number ): boolean
321+ return a > b
322+ end )
314323
315324 local n = # fpsData
316325 if n == 0 then
@@ -324,8 +333,18 @@ function Harness.benchComparison(
324333 end
325334
326335 print (` │ {label }` )
327- print (` │ FPS │ Median={p (fpsData , 50 )} │ P0={p (fpsData , 0 )} │ P80={p (fpsData , 80 )} │ P90={p (fpsData , 90 )} │ P95={p (fpsData , 95 )} │ P100={p (fpsData , 100 )}` )
328- print (` │ Kbps │ Median={p (kbpsData , 50 )} │ P0={p (kbpsData , 0 )} │ P80={p (kbpsData , 80 )} │ P90={p (kbpsData , 90 )} │ P95={p (kbpsData , 95 )} │ P100={p (kbpsData , 100 )}` )
336+ print (
337+ ` │ FPS │ Median={p (fpsData , 50 )} │ P0={p (fpsData , 0 )} │ P80={p (fpsData , 80 )} │ P90={p (
338+ fpsData ,
339+ 90
340+ )} │ P95={p (fpsData , 95 )} │ P100={p (fpsData , 100 )}`
341+ )
342+ print (
343+ ` │ Kbps │ Median={p (kbpsData , 50 )} │ P0={p (kbpsData , 0 )} │ P80={p (
344+ kbpsData ,
345+ 80
346+ )} │ P90={p (kbpsData , 90 )} │ P95={p (kbpsData , 95 )} │ P100={p (kbpsData , 100 )}`
347+ )
329348 print (` │ Sent={sent } Samples={n }` )
330349end
331350
0 commit comments