Skip to content

cmd/compile: if x == a || x == b || x == c generates slower code than case a, b, c #19791

@gaal

Description

@gaal

go version devel +214be5b302 Sun Mar 26 04:40:20 2017 +0000 linux/amd64

While investigating issue 19789 I came across code that rans 25% slower than I expected. Context with runnable benchmark: https://gist.github.com/gaal/497361737dd55125cf2de998b49d948b

Please compare:

// BenchmarkFields/FieldsFuncLatin1Switch-12                1000000              2177 ns/op          78.08 MB/s
// BenchmarkFields/FieldsFuncLatin1If-12                     500000              2970 ns/op          57.24 MB/s

// isLatin1SpaceSwitch is is like unicode.IsSpace, but without the Unicode support.
// Presumably generates a jump table.
func isLatin1SpaceSwitch(r rune) bool {
	switch r {
	case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
		return true
	}
	return false
}

// Equivalent to isLatin1SpaceSwitch, but apparently generates much slower code.
func isLatin1SpaceIf(r rune) bool {
	return r == '\t' ||
		r == '\n' ||
		r == '\v' ||
		r == '\f' ||
		r == '\r' ||
		r == ' ' ||
		r == 0x85 ||
		r == 0xA0
}

It looks like the compiler could figure out that the expression is equivalent and could be optimized the same way. The speedup probably depends greatly on the number and kinds of arguments in the disjunction.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions