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…
Reference in New Issue
Block a user