v2 / examples / js_dom_draw_benchmark_chart / chart / main.v
241 lines · 203 sloc · 6.87 KB · 5d91447d09493d073ae7b8cb1c45a4a00de9222d
Raw
1module main
2
3import veb
4import os
5import json
6import arrays
7import net.http
8import math
9import v.util.version
10
11@[table: 'benchmark']
12struct Task {
13mut:
14 id u32 @[primary; serial; sql: serial]
15 title string
16 status string
17}
18
19struct FrameworkBenchmarkResponse {
20 insert []int
21 select []int
22 update []int
23}
24
25struct FrameworkPlatform {
26mut:
27 v_sqlite_memory []int
28 // v_sqlite_file []int
29 typescript_sqlite_memory []int
30}
31
32fn (framework_platform FrameworkPlatform) to_map() map[string][]int {
33 mut mapa := map[string][]int{}
34
35 mapa['v_sqlite_memory'] = framework_platform.v_sqlite_memory
36 // mapa['v_sqlite_file'] = framework_platform.v_sqlite_file
37 mapa['typescript_sqlite_memory'] = framework_platform.typescript_sqlite_memory
38 return mapa
39}
40
41const http_port = 3001
42const benchmark_loop_length = 20
43
44pub struct Context {
45 veb.Context
46}
47
48struct App {
49 veb.StaticHandler
50}
51
52enum SqliteDbConnection {
53 sqlite_memory
54 sqlite_file
55}
56
57fn main() {
58 mut app := &App{}
59 app.serve_static('/favicon.ico', 'favicon.ico') or { panic(err) }
60 app.serve_static('/draw.js', 'draw.js') or { panic(err) }
61 app.mount_static_folder_at(os.resource_abs_path('.'), '/') or { panic(err) }
62
63 veb.run[App, Context](mut app, http_port)
64}
65
66pub fn (app &App) before_request(mut ctx Context) {
67 os.execute_or_panic('v -b js_browser draw.js.v ')
68}
69
70@['/'; get]
71pub fn (mut app App) controller_get_all_task(mut ctx Context) !veb.Result {
72 v_version := version.full_v_version(true)
73 orm_stmt_kinds := ['insert', 'select', 'update']
74
75 mut attribute_names := map[string][]string{}
76 // Used to garante the chart proposionalite
77 mut max_benchmark := map[string]int{}
78 mut from_framework := map[string]string{}
79 mut maxs := map[string][]int{}
80 mut framework_platform := map[string]map[string][]int{}
81 mut table := map[string]map[string]map[string]string{}
82
83 chart_colors := ['gray', 'red', 'orange', 'purple', 'red', 'orange', 'purple']
84 for orm_stmt_kind in orm_stmt_kinds {
85 match orm_stmt_kind {
86 'insert' {
87 framework_platform[orm_stmt_kind] = insert_framework_benchmark_times() or {
88 return error('')
89 }.to_map()
90 }
91 'select' {
92 framework_platform[orm_stmt_kind] = select_framework_benchmark_times() or {
93 return error('')
94 }.to_map()
95 }
96 'update' {
97 framework_platform[orm_stmt_kind] = update_framework_benchmark_times() or {
98 return error('')
99 }.to_map()
100 }
101 else {}
102 }
103
104 for key, values in framework_platform[orm_stmt_kind] {
105 attribute_names[orm_stmt_kind] << key
106 maxs[orm_stmt_kind] << arrays.max(values) or { continue }
107 }
108
109 from_framework[orm_stmt_kind] = json.encode(framework_platform[orm_stmt_kind])
110 table[orm_stmt_kind] = gen_table_info(attribute_names[orm_stmt_kind],
111 framework_platform[orm_stmt_kind])
112 max_benchmark[orm_stmt_kind] = arrays.max(maxs[orm_stmt_kind]) or { continue }
113 }
114
115 return $veb.html()
116}
117
118fn insert_framework_benchmark_times() !FrameworkPlatform {
119 numbers := FrameworkPlatform{
120 v_sqlite_memory: v_sqlite_memory()!.insert
121 // v_sqlite_file: v_sqlite_file()!.insert
122 typescript_sqlite_memory: typescript_sqlite_memory()!.insert
123 }
124
125 return numbers
126}
127
128fn select_framework_benchmark_times() !FrameworkPlatform {
129 numbers := FrameworkPlatform{
130 v_sqlite_memory: v_sqlite_memory()!.select
131 // v_sqlite_file: v_sqlite_file()!.select
132 typescript_sqlite_memory: typescript_sqlite_memory()!.select
133 }
134
135 return numbers
136}
137
138fn update_framework_benchmark_times() !FrameworkPlatform {
139 numbers := FrameworkPlatform{
140 v_sqlite_memory: v_sqlite_memory()!.update
141 // v_sqlite_file: v_sqlite_file()!.select
142 typescript_sqlite_memory: typescript_sqlite_memory()!.update
143 }
144
145 return numbers
146}
147
148fn typescript_sqlite_memory() !FrameworkBenchmarkResponse {
149 url := 'http://localhost:3000/sqlite-memory/${benchmark_loop_length}'
150 res := http.get(url) or { panic(err) }
151 framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
152 return framework_benchmark_response
153}
154
155fn v_sqlite_memory() !FrameworkBenchmarkResponse {
156 url := 'http://localhost:4000/sqlite-memory/${benchmark_loop_length}'
157 res := http.get(url) or { panic(err) }
158 framework_benchmark_response := json.decode(FrameworkBenchmarkResponse, res.body)!
159 return framework_benchmark_response
160}
161
162fn gen_table_info(attribute_names []string, framework_platform map[string][]int) map[string]map[string]string {
163 mut table := map[string]map[string]string{}
164
165 // nanoseconds
166 mut max_times := map[string]int{}
167 mut ten_perc_max_times := map[string]int{}
168 mut min_times := map[string]int{}
169 mut ten_perc_min_times := map[string]int{}
170
171 // bigger to calculate percent
172 mut max := 0.0
173 mut ten_perc_max := 0.0
174 mut min := 0.0
175 mut ten_perc_min := 0.0
176
177 // percentes
178 mut max_fast := map[string]int{}
179 mut ten_perc_max_fast := map[string]int{}
180 mut min_fast := map[string]int{}
181 mut ten_perc_min_fast := map[string]int{}
182
183 // nanoseconds
184 for idx, name in attribute_names {
185 // qtd. of values in 10 % of arrays
186 ten_perc := int(framework_platform[name].len / 10)
187
188 // get 10% higher
189 mut min_ten_array := framework_platform[name].clone()
190 min_ten_array.sort()
191 min_ten_array.trim(ten_perc)
192
193 // get 10% lower
194 mut max_ten_array := framework_platform[name].clone()
195 max_ten_array.sort(a > b)
196 max_ten_array.trim(ten_perc)
197
198 // popule array with nanoseconds to which benchmark
199 max_times[name] = arrays.max(framework_platform[name]) or { 0 } // int
200 ten_perc_max_times[name] = arrays.sum(max_ten_array) or { 0 } / ten_perc // int
201 min_times[name] = arrays.min(framework_platform[name]) or { 0 } // int
202 ten_perc_min_times[name] = arrays.sum(min_ten_array) or { 0 } / ten_perc // int
203
204 // set bigger values
205 if idx < 1 {
206 max = f64(max_times[name])
207 ten_perc_max = f64(ten_perc_max_times[name])
208 min = f64(min_times[name])
209 ten_perc_min = f64(ten_perc_min_times[name])
210 } else {
211 if max < f64(max_times[name]) {
212 max = f64(max_times[name])
213 }
214 if ten_perc_max < f64(ten_perc_max_times[name]) {
215 ten_perc_max = f64(ten_perc_max_times[name])
216 }
217 if min < f64(min_times[name]) {
218 min = f64(min_times[name])
219 }
220 if ten_perc_min < f64(ten_perc_min_times[name]) {
221 ten_perc_min = f64(ten_perc_min_times[name])
222 }
223 }
224 }
225
226 // percents
227 for name in attribute_names {
228 max_fast[name] = int(max / f64(max_times[name]))
229 ten_perc_max_fast[name] = int(ten_perc_max / f64(ten_perc_max_times[name]))
230 min_fast[name] = int(min / f64(min_times[name]))
231 ten_perc_min_fast[name] = int(ten_perc_min / f64(ten_perc_min_times[name]))
232 }
233
234 for name in attribute_names {
235 table[name]['max.'] = '${math.round_sig(f64(max_times[name]) / 1000000, 2)} ms (${max_fast[name]}x faster)'
236 table[name]['10% max.'] = '${math.round_sig(f64(ten_perc_max_times[name]) / 1000000, 2)} ms (${ten_perc_max_fast[name]}x faster)'
237 table[name]['min.'] = '${math.round_sig(f64(min_times[name]) / 1000000, 2)} ms (${min_fast[name]}x faster)'
238 table[name]['10% min.'] = '${math.round_sig(f64(ten_perc_min_times[name]) / 1000000, 2)} ms (${ten_perc_min_fast[name]}x faster)'
239 }
240 return table
241}
242