From 6583d3c7267e79e4d00515621c72a5ea9d747963 Mon Sep 17 00:00:00 2001 From: Hitalo Souza Date: Fri, 18 Oct 2024 02:12:09 -0400 Subject: [PATCH] x.json2.decoder2: improve decode array (#22556) --- vlib/x/json2/decoder2/decode.v | 30 ++++++++++++++++++- vlib/x/json2/decoder2/tests/bench.v | 16 ++++++++++ .../json2/decoder2/tests/decode_array_test.v | 5 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 vlib/x/json2/decoder2/tests/decode_array_test.v diff --git a/vlib/x/json2/decoder2/decode.v b/vlib/x/json2/decoder2/decode.v index 4d7236226b..6147594397 100644 --- a/vlib/x/json2/decoder2/decode.v +++ b/vlib/x/json2/decoder2/decode.v @@ -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 @@ -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 @@ -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 // diff --git a/vlib/x/json2/decoder2/tests/bench.v b/vlib/x/json2/decoder2/tests/bench.v index 8b29006028..95ba4ea25d 100644 --- a/vlib/x/json2/decoder2/tests/bench.v +++ b/vlib/x/json2/decoder2/tests/bench.v @@ -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 ********************************************************** diff --git a/vlib/x/json2/decoder2/tests/decode_array_test.v b/vlib/x/json2/decoder2/tests/decode_array_test.v new file mode 100644 index 0000000000..1eea65f5ee --- /dev/null +++ b/vlib/x/json2/decoder2/tests/decode_array_test.v @@ -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] +}