What is the best way to check that Go string and a byte slice contain the same bytes? The simplest str == string(byteSlice)
is inefficient as it copies byteSlice
first.
I was looking for a version of Equal(a, b []byte) that takes a string as its argument, but could not find anything suitable.
Starting from Go 1.5 the compiler optimizes string(bytes) when comparing to a string using a stack-allocated temporary. Thus since Go 1.5
str == string(byteSlice)
became a canonical and efficient way to compare string to a byte slice.
The Go Programming Language Specification
String types
A string type represents the set of string values. A string value is a (possibly empty) sequence of bytes. The predeclared string type is string.
The length of a string s (its size in bytes) can be discovered using the built-in function len. A string's bytes can be accessed by integer indices 0 through len(s)-1.
For example,
package main
import "fmt"
func equal(s string, b []byte) bool {
if len(s) != len(b) {
return false
}
for i, x := range b {
if x != s[i] {
return false
}
}
return true
}
func main() {
s := "equal"
b := []byte(s)
fmt.Println(equal(s, b))
s = "not" + s
fmt.Println(equal(s, b))
}
Output:
true
false
If you're comfortable enough with the fact that this can break on a later release (doubtful though), you can use unsafe
:
func unsafeCompare(a string, b []byte) int {
abp := *(*[]byte)(unsafe.Pointer(&a))
return bytes.Compare(abp, b)
}
func unsafeEqual(a string, b []byte) bool {
bbp := *(*string)(unsafe.Pointer(&b))
return a == bbp
}
playground
Benchmarks:
// using:
// aaa = strings.Repeat("a", 100)
// bbb = []byte(strings.Repeat("a", 99) + "b")
// go 1.5
BenchmarkCopy-8 20000000 75.4 ns/op
BenchmarkPetersEqual-8 20000000 83.1 ns/op
BenchmarkUnsafe-8 100000000 12.2 ns/op
BenchmarkUnsafeEqual-8 200000000 8.94 ns/op
// go 1.4
BenchmarkCopy 10000000 233 ns/op
BenchmarkPetersEqual 20000000 72.3 ns/op
BenchmarkUnsafe 100000000 15.5 ns/op
BenchmarkUnsafeEqual 100000000 10.7 ns/op
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With