gen: optimize `str == ''` to `str.len == 0` for performance (#6527)

pull/6529/head
spaceface777 2020-10-01 22:28:44 +02:00 committed by GitHub
parent d595e03928
commit f55f2fb9d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 50 additions and 36 deletions

View File

@ -2390,39 +2390,49 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
g.write(', ') g.write(', ')
g.expr(node.right) g.expr(node.right)
g.write(')') g.write(')')
} else if left_type == table.string_type_idx && node.op != .key_in && node.op != .not_in { } else if left_type == table.string_type_idx && node.op !in [.key_in, .not_in] {
fn_name := match node.op { // `str == ''` -> `str.len == 0` optimization
.plus { if node.op in [.eq, .ne] &&
'string_add(' node.right is ast.StringLiteral && (node.right as ast.StringLiteral).val == '' {
} arrow := if left_type.is_ptr() { '->' } else { '.' }
.eq { g.write('(')
'string_eq(' g.expr(node.left)
} g.write(')')
.ne { g.write('${arrow}len $node.op 0')
'string_ne(' } else {
} fn_name := match node.op {
.lt { .plus {
'string_lt(' 'string_add('
} }
.le { .eq {
'string_le(' 'string_eq('
} }
.gt { .ne {
'string_gt(' 'string_ne('
} }
.ge { .lt {
'string_ge(' 'string_lt('
} }
else { .le {
verror('op error for type `$left_sym.name`') 'string_le('
'/*node error*/' }
.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 { } else if node.op in [.eq, .ne] && left_sym.kind == .array && right_sym.kind == .array {
ptr_typ := g.gen_array_equality_fn(left_type) ptr_typ := g.gen_array_equality_fn(left_type)
if node.op == .eq { if node.op == .eq {
@ -2723,11 +2733,15 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
} }
g.expr(expr) g.expr(expr)
} else if type_sym.kind == .string { } else if type_sym.kind == .string {
g.write('string_eq(') if (expr as ast.StringLiteral).val == '' {
g.write(cond_var) g.write('${cond_var}.len == 0')
g.write(', ') } else {
g.expr(expr) g.write('string_eq(')
g.write(')') g.write(cond_var)
g.write(', ')
g.expr(expr)
g.write(')')
}
} else if expr is ast.RangeExpr { } else if expr is ast.RangeExpr {
// if type is unsigned and low is 0, check is unneeded // if type is unsigned and low is 0, check is unneeded
mut skip_low := false mut skip_low := false