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.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