Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf, refactor: simplify and performe strings #8

Merged
merged 1 commit into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ pub fn (mut d Decoder) decode_to_json[T](src []u8) !string {
d.buffer = src
d.next()!

mut result := ''
mut result := []u8{}

defer {
unsafe { result.free() }
}

data := d.buffer

Expand All @@ -41,72 +45,75 @@ pub fn (mut d Decoder) decode_to_json[T](src []u8) !string {

mut d_for_array := new_decoder()

result += '['
result << `[`

for i in 0 .. array_len {
if i > 0 {
result += ','
result << `,`
}

element_json := d_for_array.decode_to_json[T](data[1..]) or {
return error('error converting array element to JSON ${err}')
}

result += element_json
unsafe { result.push_many(element_json.str, element_json.len) }
}

result += ']'
result << `]`
}
mp_map_16, mp_map_32, mp_fix_map_min...mp_fix_map_max {
map_len := d.read_map_len(src) or { return error('error reading map length') }

result += '{'
result << `{`

for i in 0 .. map_len {
if i > 0 {
result += ','
result << `,`
}

key := d.decode_to_json[string](src) or {
return error('error converting map key to JSON: ${err}')
}
unsafe { result.push_many(key.str, key.len) }
result << `:`

value_json := d.decode_to_json[T](src) or {
return error('error converting map value to JSON')
}

result += '${key}:${value_json}'
unsafe { result.push_many(value_json.str().str, value_json.str().len) }
}

result += '}'
result << `}`
}
mp_nil {
result += 'null'
unsafe { result.push_many('null'.str, 'null'.len) }
}
mp_true, mp_false {
mut bool_val := false
d.decode_bool(mut bool_val) or { return error('error decoding boolean: ${err}') }
result += bool_val.str()
unsafe { result.push_many(bool_val.str().str, bool_val.str().len) }
}
mp_f32, mp_f64 {
mut float_val := 0.0
d.decode_float(mut float_val) or { return error('error decoding float: ${err}') }
result += float_val.str()
unsafe { result.push_many(float_val.str().str, float_val.str().len) }
}
mp_u8, mp_u16, mp_u32, mp_u64, mp_i8, mp_i16, mp_i32, mp_i64 {
mut int_val := 0
d.decode_integer(mut int_val) or { return error('error decoding integer: ${err}') }
result += int_val.str()
unsafe { result.push_many(int_val.str().str, int_val.str().len) }
}
mp_str_8, mp_str_16, mp_str_32, mp_fix_str_min...mp_fix_str_max {
mut str_val := ''
d.decode_string(mut str_val) or { return error('error decoding string: ${err}') }
result += '"${str_val}"'
result << `\"`
unsafe { result.push_many(str_val.str, str_val.len) }
result << `\"`
}
mp_bin_8, mp_bin_16, mp_bin_32 {
bin_len := d.read_bin_len(src) or { return error('error reading binary length') }
for i in 0 .. bin_len {
result += src[d.pos + i].str()
unsafe { result.push_many(src[d.pos + i].str().str, src[d.pos + i].str().len) }
}

d.pos += bin_len
Expand All @@ -117,7 +124,7 @@ pub fn (mut d Decoder) decode_to_json[T](src []u8) !string {
return error('unsupported descriptor byte for conversion to JSON')
}
}
return result
return result.bytestr()
}

pub fn decode[T](src []u8) !T {
Expand Down
17 changes: 9 additions & 8 deletions encode.v
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
module msgpack

import strings
import math
import time

struct Encoder {
mut:
buffer strings.Builder = strings.new_builder(1024)
buffer []u8
config Config = default_config()
}

Expand Down Expand Up @@ -114,9 +113,9 @@ pub fn (mut e Encoder) encode[T](data T) []u8 {

pub fn (mut e Encoder) encode_bool(b bool) {
if b {
e.buffer.write_u8(mp_true)
e.buffer << mp_true
} else {
e.buffer.write_u8(mp_false)
e.buffer << mp_false
}
}

Expand Down Expand Up @@ -354,7 +353,9 @@ pub fn (mut e Encoder) write_map_start(length int) {
}

fn (mut e Encoder) write_string(s string) {
e.buffer.write_string(s)
if s.len > 0 {
unsafe { e.buffer.push_many(s.str, s.len) }
}
}

fn (mut e Encoder) write_u16(i u16) {
Expand All @@ -379,14 +380,14 @@ pub fn (mut e Encoder) write_f64(f f64) {

// write byte array
fn (mut e Encoder) write(b []u8) {
e.buffer.write(b) or { panic('write error') }
unsafe { e.buffer.push_many(b.bytestr().str, b.bytestr().len) }
}

// write one or more bytes
fn (mut e Encoder) write_u8(b ...u8) {
if b.len > 1 {
e.write(b)
e.buffer << b
} else {
e.buffer.write_u8(b[0])
e.buffer << b[0]
}
}
13 changes: 7 additions & 6 deletions examples/bench_msgpack_json_vs_json2.v
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ import os
import json
import x.json2
import msgpack
import time
import benchmark
// import time

struct Person {
name string
age int
created_at time.Time
name string
age int
// created_at time.Time
}

fn main() {
max_iterations := os.getenv_opt('MAX_ITERATIONS') or { '1000' }.int()
s := '{"name":"Bilbo Baggins","age":99,"created_at":1670840340}'
max_iterations := os.getenv_opt('MAX_ITERATIONS') or { '1000000' }.int()
// s := '{"name":"Bilbo Baggins","age":99,"created_at":1670840340}'
s := '{"name":"Bilbo Baggins","age":99}'
mut b := benchmark.start()

for _ in 0 .. max_iterations {
Expand Down
Loading