mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
examples: V orm still fast? (#15330)
This commit is contained in:
parent
0b1486f014
commit
ee9142a113
3
examples/js_dom_draw_bechmark_chart/.gitignore
vendored
Normal file
3
examples/js_dom_draw_bechmark_chart/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.js
|
||||||
|
*.exe
|
||||||
|
*.db
|
7
examples/js_dom_draw_bechmark_chart/Dockerfile
Normal file
7
examples/js_dom_draw_bechmark_chart/Dockerfile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
FROM thevlang/vlang:alpine-dev
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN v up && v -prod main.v
|
27
examples/js_dom_draw_bechmark_chart/README.md
Normal file
27
examples/js_dom_draw_bechmark_chart/README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# To run app
|
||||||
|
Dockerfile
|
||||||
|
[docker build]=> Docker image
|
||||||
|
[docker run]=> Docker container
|
||||||
|
|
||||||
|
`sudo docker build -t <name> .`
|
||||||
|
|
||||||
|
`sudo docker run --name <container name> --interactive --tty --publish 3001:3001 <name>`
|
||||||
|
|
||||||
|
`v run .`
|
||||||
|
|
||||||
|
A message like `[Vweb] Running app on http://localhost:3001/` should appear
|
||||||
|
|
||||||
|
`exit`
|
||||||
|
|
||||||
|
# To implement new bechmarks
|
||||||
|
|
||||||
|
create a function to bench in main.v like `fn any_function() []int {}`
|
||||||
|
that must factory return the array of time spended.
|
||||||
|
So set the attribute in canvas (with id "canvas_insert_id")
|
||||||
|
In draw.js.v put the attribute name inside of attribute_names array
|
||||||
|
|
||||||
|
|
||||||
|
# ROADMAP
|
||||||
|
02/09/2022
|
||||||
|
- [ ] select bench (easy)
|
||||||
|
- [ ] vsql (easy)
|
111
examples/js_dom_draw_bechmark_chart/draw.js.v
Normal file
111
examples/js_dom_draw_bechmark_chart/draw.js.v
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import js.dom
|
||||||
|
|
||||||
|
fn get_canvas(elem JS.HTMLElement) JS.HTMLCanvasElement {
|
||||||
|
match elem {
|
||||||
|
JS.HTMLCanvasElement {
|
||||||
|
return elem
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic('Not a canvas')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_line(mut context JS.CanvasRenderingContext2D, x1 int, y1 int, x2 int, y2 int) {
|
||||||
|
context.beginPath()
|
||||||
|
context.strokeStyle = 'black'.str
|
||||||
|
context.lineWidth = JS.Number(1)
|
||||||
|
context.moveTo(0, 0)
|
||||||
|
context.lineTo(100, 100)
|
||||||
|
context.stroke()
|
||||||
|
context.closePath()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DrawState {
|
||||||
|
mut:
|
||||||
|
context JS.CanvasRenderingContext2D
|
||||||
|
drawing bool
|
||||||
|
x f64
|
||||||
|
y f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut state DrawState) draw_bench_chart(color string, time_array []int, max_time int) ? {
|
||||||
|
println(time_array.len)
|
||||||
|
max_height := f64(480)
|
||||||
|
max_width := f64(720)
|
||||||
|
|
||||||
|
state.drawing = true
|
||||||
|
state.x = f64(0)
|
||||||
|
state.y = f64(max_height)
|
||||||
|
state.context.strokeStyle = color.str
|
||||||
|
state.context.lineWidth = JS.Number(1)
|
||||||
|
|
||||||
|
for i := 0; i <= time_array.len; i++ {
|
||||||
|
state.context.beginPath()
|
||||||
|
state.context.moveTo(state.x, state.y)
|
||||||
|
state.x = max_width / f64(time_array.len) * i + 1.0
|
||||||
|
state.y = max_height - (max_height / f64(max_time) * f64(time_array[i]))
|
||||||
|
state.context.lineTo(state.x, state.y)
|
||||||
|
state.context.stroke()
|
||||||
|
state.context.closePath()
|
||||||
|
}
|
||||||
|
|
||||||
|
state.drawing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
document := dom.document
|
||||||
|
|
||||||
|
clear_btn := document.getElementById('clearButton'.str)?
|
||||||
|
|
||||||
|
canvas_elem := document.getElementById('canvas_insert_id'.str)?
|
||||||
|
|
||||||
|
canvas := get_canvas(canvas_elem)
|
||||||
|
ctx := canvas.getContext('2d'.str, js_undefined())?
|
||||||
|
context := match ctx {
|
||||||
|
JS.CanvasRenderingContext2D {
|
||||||
|
ctx
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
panic('can not get 2d context')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mut state := DrawState{context, false, 0, 0}
|
||||||
|
|
||||||
|
attribute_names := ['sqlite_memory_insert_times', 'sqlite_file_insert_times' /*
|
||||||
|
,
|
||||||
|
'postgres_insert_times', 'mysql_insert_times'
|
||||||
|
*/]
|
||||||
|
chart_colors := ['gray', 'black', 'red', 'orange', 'purple']
|
||||||
|
|
||||||
|
for idx, name in attribute_names {
|
||||||
|
// get values in JS.String values
|
||||||
|
mut attribute_js_values := canvas_elem.getAttribute(name.str) or {
|
||||||
|
println('Não pegou o attributo')
|
||||||
|
continue // if attribute not exist, jump.
|
||||||
|
}
|
||||||
|
if attribute_js_values.length < JS.Number(1) {
|
||||||
|
continue // if attribute value is empty, jump.
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert []JS.String in v []string
|
||||||
|
mut attribute_string_values := tos(attribute_js_values).replace('[', '').replace(']',
|
||||||
|
'').split(',')
|
||||||
|
|
||||||
|
// convert []string in []int
|
||||||
|
mut attribute_int_values := []int{}
|
||||||
|
for variable in attribute_string_values {
|
||||||
|
attribute_int_values << variable.int()
|
||||||
|
}
|
||||||
|
// draw chart
|
||||||
|
state.draw_bench_chart(chart_colors[idx], attribute_int_values, 11204530) or {
|
||||||
|
println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_btn.addEventListener('click'.str, fn [mut state, canvas] (_ JS.Event) {
|
||||||
|
state.context.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
}, JS.EventListenerOptions{})
|
||||||
|
}
|
217
examples/js_dom_draw_bechmark_chart/main.v
Normal file
217
examples/js_dom_draw_bechmark_chart/main.v
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
import vweb
|
||||||
|
import os
|
||||||
|
import sqlite
|
||||||
|
// import pg
|
||||||
|
// import mysql
|
||||||
|
import time
|
||||||
|
import arrays
|
||||||
|
|
||||||
|
[table: 'benchmark']
|
||||||
|
struct Task {
|
||||||
|
mut:
|
||||||
|
id u32 [primary; serial; sql: serial]
|
||||||
|
title string
|
||||||
|
status string
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
http_port = 3001
|
||||||
|
benchmark_loop_length = 10
|
||||||
|
)
|
||||||
|
|
||||||
|
struct App {
|
||||||
|
vweb.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SqliteDbConnection {
|
||||||
|
sqlite_memory
|
||||||
|
sqlite_file
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
vweb.run(new_app(), http_port)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut app App) before_request() {
|
||||||
|
os.execute_or_panic('v -b js_browser draw.js.v ')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_app() &App {
|
||||||
|
mut app := &App{}
|
||||||
|
app.serve_static('/favicon.ico', 'favicon.ico')
|
||||||
|
app.serve_static('/draw.js', 'draw.js')
|
||||||
|
app.mount_static_folder_at(os.resource_abs_path('.'), '/')
|
||||||
|
return app
|
||||||
|
}
|
||||||
|
|
||||||
|
['/'; get]
|
||||||
|
pub fn (mut app App) controller_get_all_task() vweb.Result {
|
||||||
|
// attribute_names := ['sqlite_memory_insert_times', 'sqlite_file_insert_times',
|
||||||
|
// 'postgres_insert_times', 'mysql_insert_times']
|
||||||
|
attribute_names := ['sqlite_memory_insert_times', 'sqlite_file_insert_times']
|
||||||
|
chart_colors := ['gray', 'black', 'red', 'orange', 'purple']
|
||||||
|
mut insert_times := [][]int{}
|
||||||
|
|
||||||
|
mut max_times := []int{}
|
||||||
|
mut ten_perc_max_times := []int{}
|
||||||
|
mut min_times := []int{}
|
||||||
|
mut ten_perc_min_times := []int{}
|
||||||
|
|
||||||
|
mut max_fast := []int{}
|
||||||
|
mut ten_perc_max_fast := []int{}
|
||||||
|
mut min_fast := []int{}
|
||||||
|
mut ten_perc_min_fast := []int{}
|
||||||
|
|
||||||
|
insert_times << factory_sqlite_memory_insert_benchmark(.sqlite_memory)
|
||||||
|
insert_times << factory_sqlite_memory_insert_benchmark(.sqlite_file)
|
||||||
|
// insert_times << factory_postgres_insert_benchmark()
|
||||||
|
// insert_times << factory_mysql_insert_benchmark()
|
||||||
|
|
||||||
|
sqlite_memory_insert_times := insert_times[0].str().replace(' ', '')
|
||||||
|
sqlite_file_insert_times := insert_times[1].str().replace(' ', '')
|
||||||
|
// postgres_insert_times := insert_times[2].str().replace(' ', '')
|
||||||
|
// mysql_insert_times := insert_times[3].str().replace(' ', '')
|
||||||
|
|
||||||
|
for i := 0; i < attribute_names.len; i++ {
|
||||||
|
println('insert_times[i]: ${insert_times[i]}')
|
||||||
|
ten_perc := int(insert_times[i].len / 10)
|
||||||
|
|
||||||
|
mut min_ten_array := insert_times[i].clone()
|
||||||
|
min_ten_array.sort()
|
||||||
|
min_ten_array.trim(ten_perc)
|
||||||
|
|
||||||
|
mut max_ten_array := insert_times[i].clone()
|
||||||
|
max_ten_array.sort(a > b)
|
||||||
|
max_ten_array.trim(ten_perc)
|
||||||
|
|
||||||
|
max_times << arrays.max(insert_times[i]) or { 0 }
|
||||||
|
ten_perc_max_times << arrays.sum(max_ten_array) or { 0 } / ten_perc
|
||||||
|
min_times << arrays.min(insert_times[i]) or { 0 }
|
||||||
|
ten_perc_min_times << arrays.sum(min_ten_array) or { 0 } / ten_perc
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < attribute_names.len; i++ {
|
||||||
|
max_fast << int(100 - (f64(max_times[i] * 100) / f64(arrays.max(max_times) or {
|
||||||
|
panic('deu ruim no max_fas')
|
||||||
|
})))
|
||||||
|
ten_perc_max_fast << int(100 - (f64(ten_perc_max_times[i] * 100) / f64(arrays.max(ten_perc_max_times) or {
|
||||||
|
panic('deu ruim no max_fas')
|
||||||
|
})))
|
||||||
|
min_fast << int(100 - (f64(min_times[i] * 100) / f64(arrays.max(min_times) or {
|
||||||
|
panic('deu ruim no max_fas')
|
||||||
|
})))
|
||||||
|
ten_perc_min_fast << int(100 - (f64(ten_perc_min_times[i] * 100) / f64(arrays.max(ten_perc_min_times) or {
|
||||||
|
panic('deu ruim no max_fas')
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
|
return $vweb.html()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn factory_sqlite_memory_insert_benchmark(db_connection SqliteDbConnection) []int {
|
||||||
|
mut result := []int{}
|
||||||
|
mut sw := time.new_stopwatch()
|
||||||
|
mut db := sqlite.connect(':memory:') or { panic(err) }
|
||||||
|
|
||||||
|
if db_connection == .sqlite_file {
|
||||||
|
db.close() or { println('text: $err') }
|
||||||
|
db = sqlite.connect('salada.db') or { panic(err) }
|
||||||
|
}
|
||||||
|
|
||||||
|
sql db {
|
||||||
|
create table Task
|
||||||
|
}
|
||||||
|
|
||||||
|
task_model := Task{
|
||||||
|
title: 'a'
|
||||||
|
status: 'done'
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < benchmark_loop_length; i++ {
|
||||||
|
sw.start()
|
||||||
|
sql db {
|
||||||
|
insert task_model into Task
|
||||||
|
}
|
||||||
|
sw.stop()
|
||||||
|
result << int(sw.end - sw.start)
|
||||||
|
}
|
||||||
|
|
||||||
|
sql db {
|
||||||
|
drop table Task
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn factory_postgres_insert_benchmark() []int {
|
||||||
|
// mut result := []int{}
|
||||||
|
// mut sw := time.new_stopwatch()
|
||||||
|
|
||||||
|
// mut db := pg.connect(pg.Config{
|
||||||
|
// host: '127.0.0.1'
|
||||||
|
// port: 5432
|
||||||
|
// user: 'hitalo'
|
||||||
|
// password: 'password'
|
||||||
|
// dbname: 'username'
|
||||||
|
// }) or { panic(err) }
|
||||||
|
// sql db {
|
||||||
|
// create table Task
|
||||||
|
// }
|
||||||
|
|
||||||
|
// task_model := Task{
|
||||||
|
// title: 'a'
|
||||||
|
// status: 'done'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for i := 0; i < benchmark_loop_length; i++ {
|
||||||
|
// sw.start()
|
||||||
|
// sql db {
|
||||||
|
// insert task_model into Task
|
||||||
|
// }
|
||||||
|
// sw.stop()
|
||||||
|
// result << int(sw.end - sw.start)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sql db {
|
||||||
|
// drop table Task
|
||||||
|
// }
|
||||||
|
// return result
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn factory_mysql_insert_benchmark() []int {
|
||||||
|
// mut result := []int{}
|
||||||
|
// mut sw := time.new_stopwatch()
|
||||||
|
|
||||||
|
// mut db := mysql.Connection{
|
||||||
|
// host: '127.0.0.1'
|
||||||
|
// port: 3306
|
||||||
|
// username: 'username'
|
||||||
|
// password: 'password'
|
||||||
|
// dbname: 'benchmark'
|
||||||
|
// }
|
||||||
|
// db.connect() or { println(err) }
|
||||||
|
|
||||||
|
// sql db {
|
||||||
|
// create table Task
|
||||||
|
// }
|
||||||
|
|
||||||
|
// task_model := Task{
|
||||||
|
// title: 'a'
|
||||||
|
// status: 'done'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for i := 0; i < benchmark_loop_length; i++ {
|
||||||
|
// sw.start()
|
||||||
|
// sql db {
|
||||||
|
// insert task_model into Task
|
||||||
|
// }
|
||||||
|
// sw.stop()
|
||||||
|
// result << int(sw.end - sw.start)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sql db {
|
||||||
|
// drop table Task
|
||||||
|
// }
|
||||||
|
// return result
|
||||||
|
// }
|
@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
<body class="main">
|
||||||
|
<style>
|
||||||
|
table, th, td {
|
||||||
|
border:1px solid black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<title>V orm still fast?</title>
|
||||||
|
<input type="button" id="clearButton" value="Clear canvas">
|
||||||
|
<div style="float: left; width: 100%;">
|
||||||
|
<canvas style="border: 1px solid black;" width="100" height="480" id="canvas_left_bar_id"></canvas>
|
||||||
|
<canvas sqlite_memory_insert_times=@sqlite_memory_insert_times sqlite_file_insert_times=@sqlite_file_insert_times style="border: 1px solid black;" width="720" height="480" id="canvas_insert_id"></canvas>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" src="draw.js"></script>
|
||||||
|
|
||||||
|
<h2>Insert test</h2>
|
||||||
|
|
||||||
|
<table style="width:1080px">
|
||||||
|
<tr>
|
||||||
|
<th>Benchmark name</th>
|
||||||
|
<th>max.</th>
|
||||||
|
<th>10% max.</th>
|
||||||
|
<th>min.</th>
|
||||||
|
<th>10% min.</th>
|
||||||
|
</tr>
|
||||||
|
@for idx, name in attribute_names
|
||||||
|
<tr style="font-family:arial; color: ${chart_colors[idx]};" >
|
||||||
|
<td id="benchmark_name"+idx >@name</td>
|
||||||
|
<td>@{max_times[idx]} ns (@{max_fast[idx]}%faster)</td>
|
||||||
|
<td>@{ten_perc_max_times[idx]} ns (@{ten_perc_max_fast[idx]}%faster)</td>
|
||||||
|
<td>@{min_times[idx]} ns (@{min_fast[idx]}%faster)</td>
|
||||||
|
<td>@{ten_perc_min_times[idx]} ns (@{ten_perc_min_fast[idx]}%faster)</td>
|
||||||
|
</tr>
|
||||||
|
@end
|
||||||
|
</table>
|
||||||
|
<p>V orm still fast?</p>
|
||||||
|
</body>
|
Loading…
x
Reference in New Issue
Block a user