1 module benchmark.benchmark;
2 
3 import std.stdio : writef, writeln, stdout;
4 import std.conv : to, text;
5 
6 void main()
7 {
8     writef("\033[2J");
9     writef("\033[1;1H");
10     stdout.flush();
11 
12     immutable height = 60;
13     immutable repeatMultiplier = 10_000;
14     immutable repeat = (height * repeatMultiplier);
15 
16     void delegate()[] benchmarks;
17 
18     string[][] results;
19 
20     benchmarks = [
21         () {
22             foreach (i; 0 .. repeat)
23             {
24                 auto pos = (i % 2) + 1;
25                 writef("\033[%d;%dH", pos, pos);
26             }
27 
28             stdout.flush();
29         }, () {
30             foreach (i; 0 .. repeat)
31             {
32                 auto pos = (i % 2) + 1;
33                 writef("\033[%d;%dH", pos, pos);
34                 stdout.flush();
35             }
36         }, () {
37             foreach (i; 0 .. repeatMultiplier)
38             {
39                 string data = "";
40 
41                 foreach (j; 0 .. height)
42                 {
43                     auto pos = ((j * i) % 2) + 1;
44                     data ~= text("\033[", pos, ";", pos, "H");
45                 }
46 
47                 writef(data);
48             }
49         }, () {
50             foreach (i; 0 .. repeatMultiplier)
51             {
52                 string data = "";
53 
54                 foreach (j; 0 .. height)
55                 {
56                     auto pos = ((j * i) % 2) + 1;
57                     data ~= text("\033[", pos, ";", pos, "H");
58                 }
59 
60                 writef(data);
61                 stdout.flush();
62             }
63         }
64     ];
65 
66     results ~= benchmark(benchmarks);
67     /+ sample output on github codespaces
68         1: 327 ms, 110 μs, and 7 hnsecs
69         2: 5 secs, 931 ms, 412 μs, and 9 hnsecs
70         3: 734 ms, 360 μs, and 3 hnsecs
71         4: 597 ms, 116 μs, and 7 hnsecs
72     +/
73 
74     benchmarks = [
75         () {
76             foreach (i; 0 .. repeat)
77             {
78                 auto character = ['1', '2'][i % 2];
79                 writef("\033[1;1H%s                                                                              %s",
80                         character, character);
81             }
82         }, () {
83             foreach (i; 0 .. repeat)
84             {
85                 auto character = ['1', '2'][i % 2];
86                 writef("\033[1;1H%s\033[1;80H%s", character, character);
87             }
88         }, () {
89             foreach (i; 0 .. repeat)
90             {
91                 auto character = ['1', '2'][i % 2];
92                 writef("\033[1;1H%s %s", character, character);
93             }
94         }, () {
95             foreach (i; 0 .. repeat)
96             {
97                 auto character = ['1', '2'][i % 2];
98                 writef("\033[1;1H%s\033[1;3H%s", character, character);
99             }
100         }, () {
101             foreach (i; 0 .. repeat)
102             {
103                 // 10 changed characters
104                 auto character = ['1', '2'][i % 2];
105                 writef("\033[1;1H%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
106                         character, " ", character, " ", character, " ",
107                         character, " ", character, " ", character, " ", character,
108                         " ", character, " ", character, " ", character);
109             }
110         }, () {
111             foreach (i; 0 .. repeat)
112             {
113                 // 10 changed characters
114                 auto character = ['1', '2'][i % 2];
115                 writef("\033[1;1H%s\033[1;3H%s\033[1;5H%s\033[1;7H%s\033[1;9H%s\033[1;11H%s\033[1;13H%s\033[1;15H%s\033[1;17H%s\033[1;19H%s",
116                         character, character, character, character, character,
117                         character, character, character, character, character);
118             }
119         },
120     ];
121 
122     results ~= benchmark(benchmarks);
123 
124     printResults(results);
125 }
126 
127 auto benchmark(void delegate()[] benchmarks)
128 {
129     import std.datetime.stopwatch : StopWatch;
130 
131     auto sw = StopWatch();
132     sw.stop();
133     sw.reset();
134 
135     string[] results;
136     foreach (benchmark; benchmarks)
137     {
138         sw.reset();
139         sw.start();
140         benchmark();
141         sw.stop();
142         stdout.flush();
143         results ~= to!string(sw.peek);
144     }
145 
146     return results;
147 }
148 
149 void printResults(string[][] results)
150 {
151     writef("\033[2J");
152     writef("\033[1;1H");
153     stdout.flush();
154     
155     foreach (r; results)
156     {
157         writeln;
158         foreach (n, string result; r)
159         {
160             writeln(n + 1, ": ", result);
161         }
162     }
163 }