Skip to content

Commit

Permalink
examples: V orm still fast? (#15330)
Browse files Browse the repository at this point in the history
  • Loading branch information
enghitalo committed Aug 8, 2022
1 parent 0b1486f commit ee9142a
Show file tree
Hide file tree
Showing 6 changed files with 403 additions and 0 deletions.
3 changes: 3 additions & 0 deletions examples/js_dom_draw_bechmark_chart/.gitignore
@@ -0,0 +1,3 @@
*.js
*.exe
*.db
7 changes: 7 additions & 0 deletions examples/js_dom_draw_bechmark_chart/Dockerfile
@@ -0,0 +1,7 @@
FROM thevlang/vlang:alpine-dev

WORKDIR /app

COPY . .

RUN v up && v -prod main.v
27 changes: 27 additions & 0 deletions examples/js_dom_draw_bechmark_chart/README.md
@@ -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 changes: 111 additions & 0 deletions examples/js_dom_draw_bechmark_chart/draw.js.v
@@ -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 changes: 217 additions & 0 deletions examples/js_dom_draw_bechmark_chart/main.v
@@ -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 comments on commit ee9142a

Please sign in to comment.