From f55f2fb9d1e0006a02412b77a24ccf42d08cbcd3 Mon Sep 17 00:00:00 2001 From: spaceface777 Date: Thu, 1 Oct 2020 22:28:44 +0200 Subject: [PATCH] gen: optimize `str == ''` to `str.len == 0` for performance (#6527) --- vlib/v/gen/cgen.v | 86 +++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 9dd78d74da..457e704639 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2390,39 +2390,49 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { g.write(', ') g.expr(node.right) g.write(')') - } else if left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in { - fn_name := match node.op { - .plus { - 'string_add(' - } - .eq { - 'string_eq(' - } - .ne { - 'string_ne(' - } - .lt { - 'string_lt(' - } - .le { - 'string_le(' - } - .gt { - 'string_gt(' - } - .ge { - 'string_ge(' - } - else { - verror('op error for type `$left_sym.name`') - '/*node error*/' + } else if left_type == table.string_type_idx && node.op !in [.key_in, .not_in] { + // `str == ''` -> `str.len == 0` optimization + if node.op in [.eq, .ne] && + node.right is ast.StringLiteral && (node.right as ast.StringLiteral).val == '' { + arrow := if left_type.is_ptr() { '->' } else { '.' } + g.write('(') + g.expr(node.left) + g.write(')') + g.write('${arrow}len $node.op 0') + } else { + fn_name := match node.op { + .plus { + 'string_add(' + } + .eq { + 'string_eq(' + } + .ne { + 'string_ne(' + } + .lt { + 'string_lt(' + } + .le { + 'string_le(' + } + .gt { + 'string_gt(' + } + .ge { + 'string_ge(' + } + else { + verror('op error for type `$left_sym.name`') + '/*node error*/' + } } + g.write(fn_name) + g.expr(node.left) + g.write(', ') + g.expr(node.right) + g.write(')') } - g.write(fn_name) - g.expr(node.left) - g.write(', ') - g.expr(node.right) - g.write(')') } else if node.op in [.eq, .ne] && left_sym.kind == .array && right_sym.kind == .array { ptr_typ := g.gen_array_equality_fn(left_type) if node.op == .eq { @@ -2723,11 +2733,15 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) { } g.expr(expr) } else if type_sym.kind == .string { - g.write('string_eq(') - g.write(cond_var) - g.write(', ') - g.expr(expr) - g.write(')') + if (expr as ast.StringLiteral).val == '' { + g.write('${cond_var}.len == 0') + } else { + g.write('string_eq(') + g.write(cond_var) + g.write(', ') + g.expr(expr) + g.write(')') + } } else if expr is ast.RangeExpr { // if type is unsigned and low is 0, check is unneeded mut skip_low := false