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

decoder2: decode array #22556

Merged
merged 8 commits into from
Oct 18, 2024
30 changes: 29 additions & 1 deletion vlib/x/json2/decoder2/decode.v
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,30 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
} $else $if T is time.Time {
} $else $if T is $map {
} $else $if T is $array {
array_info := decoder.values_info[decoder.value_info_idx]

if array_info.value_kind == .array {
array_position := array_info.position
array_end := array_position + array_info.length

decoder.value_info_idx++
for {
if decoder.value_info_idx >= decoder.values_info.len {
break
}
value_info := decoder.values_info[decoder.value_info_idx]

if value_info.position + value_info.length >= array_end {
break
}

mut array_element := create_array_element(val)

decoder.decode_value(mut &array_element)!

val << array_element
}
}
} $else $if T is $struct {
mut nodes := []Node{}
// TODO: needs performance improvements
Expand Down Expand Up @@ -547,6 +571,10 @@ fn get_value_kind(value rune) ValueKind {
}
}

fn create_array_element[T](array []T) T {
return T{}
}

// decode_optional_value_in_actual_node decodes an optional value in a node.
fn (mut decoder Decoder) decode_optional_value_in_actual_node[T](node Node, val ?T) T {
start := (node.key_pos + node.key_len) + 3
Expand Down Expand Up @@ -883,7 +911,7 @@ fn (mut decoder Decoder) fulfill_nodes(mut nodes []Node) {
// string_buffer_to_generic_number converts a buffer of bytes (data) into a generic type T and
// stores the result in the provided result pointer.
// The function supports conversion to the following types:
// - Signed integers: i8, i16, int, i64
// - Signed integers: i8, i16, i32, i64
// - Unsigned integers: u8, u16, u32, u64
// - Floating-point numbers: f32, f64
//
Expand Down
16 changes: 16 additions & 0 deletions vlib/x/json2/decoder2/tests/bench.v
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,22 @@ fn main() {

b.measure('old_json.decode(map[string]string, json_data1)!\n')

// array **********************************************************

println('\n***arrays***')

for i := 0; i < max_iterations; i++ {
_ := decoder2.decode[[]int]('[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]')!
}

b.measure("decoder2.decode[[]int]('[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]')!")

for i := 0; i < max_iterations; i++ {
_ := old_json.decode([]int, '[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]')!
}

b.measure("old_json.decode([]int, '[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]')!\n")

println('\n***simple types***')

// int **********************************************************
Expand Down
5 changes: 5 additions & 0 deletions vlib/x/json2/decoder2/tests/decode_array_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import x.json2.decoder2 as json

fn test_array_of_strings() {
assert json.decode[[]int]('[1, 2, 3]')! == [1, 2, 3]
}
Loading