@geektutu
关于该部分内容
|
## Q13 如何判断 2 个字符串切片(slice) 是相等的? |
|
|
|
<details> |
|
<summary>答案</summary> |
|
<div> |
|
|
|
go 语言中可以使用反射 `reflect.DeepEqual(a, b)` 判断 a、b 两个切片是否相等,但是通常不推荐这么做,使用反射非常影响性能。 |
|
|
|
通常采用的方式如下,遍历比较切片中的每一个元素(注意处理越界的情况)。 |
|
|
|
```go |
|
func StringSliceEqualBCE(a, b []string) bool { |
|
if len(a) != len(b) { |
|
return false |
|
} |
|
|
|
if (a == nil) != (b == nil) { |
|
return false |
|
} |
|
|
|
b = b[:len(a)] |
|
for i, v := range a { |
|
if v != b[i] { |
|
return false |
|
} |
|
} |
|
|
|
return true |
|
} |
|
``` |
|
|
|
|
|
</div> |
|
</details> |
这里我试了一下,貌似 reflect.DeepEqual 的效率实际上是比 for 循环要高的
package main
import (
"math/rand"
"reflect"
"testing"
"time"
)
var (
l = 100000
l2 = 100
s1 = generate(l)
s2 = generate(l)
s3 = generate(l * 2)
)
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
func randStringRunes(n int) string {
rand.Seed(time.Now().UnixNano())
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
func generate(n int) []string {
s := make([]string, n)
for i := 0; i < n; i++ {
s[i] = randStringRunes(l2)
}
return s
}
func cmp1(a, b []string) bool {
return reflect.DeepEqual(a, b)
}
func cmp2(a, b []string) bool {
if len(a) != len(b) {
return false
}
if (a == nil) != (b == nil) {
return false
}
b = b[:len(a)]
for i, v := range a {
if v != b[i] {
return false
}
}
return true
}
func BenchmarkReflect(b *testing.B) {
for i := 0; i < b.N; i++ {
cmp1(s1, s2)
cmp1(s1, s3)
cmp1(s1, s1)
}
}
func BenchmarkFor(b *testing.B) {
for i := 0; i < b.N; i++ {
cmp2(s1, s2)
cmp2(s1, s3)
cmp2(s1, s1)
}
}
在 l = 100000,l2=100时,
$ go test -bench=.
goos: linux
goarch: amd64
BenchmarkReflect-4 1235326 856 ns/op
BenchmarkFor-4 2890 354342 ns/op
PASS
在 l = 100,l2=100000时,
$ go test -bench=.
goos: linux
goarch: amd64
BenchmarkReflect-4 1205154 866 ns/op
BenchmarkFor-4 3315399 373 ns/op
PASS
好像只有切片长度很短时,for 循环具有优势,但是优势也并不大
@geektutu
关于该部分内容
interview-questions/qa-golang/qa-golang-1.md
Lines 298 to 331 in d4683a7
这里我试了一下,貌似
reflect.DeepEqual的效率实际上是比 for 循环要高的在
l = 100000,l2=100时,$ go test -bench=. goos: linux goarch: amd64 BenchmarkReflect-4 1235326 856 ns/op BenchmarkFor-4 2890 354342 ns/op PASS在
l = 100,l2=100000时,$ go test -bench=. goos: linux goarch: amd64 BenchmarkReflect-4 1205154 866 ns/op BenchmarkFor-4 3315399 373 ns/op PASS好像只有切片长度很短时,for 循环具有优势,但是优势也并不大