From 53ae9dda4b4cb11d479aa14f55efbc202908dbdb Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 2 May 2021 19:18:11 +0300 Subject: [PATCH] cgen: speed up auto generated Array_*_contains and Array_*_index methods Uses a.data instead of array_get, since the auto generated methods have the calls in a loop that guarantees that the bounds of the arrays will not be exceeded, thus the inner bounds checking can be skipped. Results in +5% improvement for V compiled with tcc, doing `v -o x.c cmd/v`, more with -prod. --- vlib/v/gen/c/array.v | 24 ++++++++++++------------ vlib/v/markused/markused.v | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 94f0ebdefd..c825a35548 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -471,20 +471,20 @@ fn (mut g Gen) gen_array_contains_method(left_type ast.Type) string { fn_builder.writeln('static bool ${fn_name}($left_type_str a, $elem_type_str v) {') fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {') if elem_sym.kind == .string { - fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {') + fn_builder.writeln('\t\tif (fast_string_eq(((string*)a.data)[i], v)) {') } else if elem_sym.kind == .array && left_info.elem_type.nr_muls() == 0 { ptr_typ := g.gen_array_equality_fn(left_info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {') + fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq((($elem_type_str*)a.data)[i], v)) {') } else if elem_sym.kind == .function { - fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {') + fn_builder.writeln('\t\tif (((voidptr*)a.data)[i] == v) {') } else if elem_sym.kind == .map && left_info.elem_type.nr_muls() == 0 { ptr_typ := g.gen_map_equality_fn(left_info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {') + fn_builder.writeln('\t\tif (${ptr_typ}_map_eq((($elem_type_str*)a.data)[i], v)) {') } else if elem_sym.kind == .struct_ && left_info.elem_type.nr_muls() == 0 { ptr_typ := g.gen_struct_equality_fn(left_info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {') + fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq((($elem_type_str*)a.data)[i], v)) {') } else { - fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {') + fn_builder.writeln('\t\tif ((($elem_type_str*)a.data)[i] == v) {') } fn_builder.writeln('\t\t\treturn true;') fn_builder.writeln('\t\t}') @@ -535,20 +535,20 @@ fn (mut g Gen) gen_array_index_method(left_type ast.Type) string { fn_builder.writeln('static int ${fn_name}($left_type_str a, $elem_type_str v) {') fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {') if elem_sym.kind == .string { - fn_builder.writeln('\t\tif (string_eq((*(string*)array_get(a, i)), v)) {') + fn_builder.writeln('\t\tif (fast_string_eq(((string*)a.data)[i], v)) {') } else if elem_sym.kind == .array && !info.elem_type.is_ptr() { ptr_typ := g.gen_array_equality_fn(info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq(*($elem_type_str*)array_get(a, i), v)) {') + fn_builder.writeln('\t\tif (${ptr_typ}_arr_eq((($elem_type_str*)a.data)[i], v)) {') } else if elem_sym.kind == .function && !info.elem_type.is_ptr() { - fn_builder.writeln('\t\tif ((*(voidptr*)array_get(a, i)) == v) {') + fn_builder.writeln('\t\tif (((voidptr*)a.data)[i] == v) {') } else if elem_sym.kind == .map && !info.elem_type.is_ptr() { ptr_typ := g.gen_map_equality_fn(info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_map_eq(*($elem_type_str*)array_get(a, i), v)) {') + fn_builder.writeln('\t\tif (${ptr_typ}_map_eq((($elem_type_str*)a.data)[i], v)) {') } else if elem_sym.kind == .struct_ && !info.elem_type.is_ptr() { ptr_typ := g.gen_struct_equality_fn(info.elem_type) - fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq(*($elem_type_str*)array_get(a, i), v)) {') + fn_builder.writeln('\t\tif (${ptr_typ}_struct_eq((($elem_type_str*)a.data)[i], v)) {') } else { - fn_builder.writeln('\t\tif ((*($elem_type_str*)array_get(a, i)) == v) {') + fn_builder.writeln('\t\tif ((($elem_type_str*)a.data)[i] == v) {') } fn_builder.writeln('\t\t\treturn i;') fn_builder.writeln('\t\t}') diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index 749b009483..cbe92e4abe 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -65,6 +65,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []ast.Fi '18.gt', '18.le', '18.ge', + 'fast_string_eq', // ustring. ==, !=, etc... '19.eq', '19.ne',