funcBenchmarkForStruct(b *testing.B) { var items [1024]Item for i := 0; i < b.N; i++ { length := len(items) var tmp int for k := 0; k < length; k++ { tmp = items[k].id } _ = tmp } }
funcBenchmarkRangeIndexStruct(b *testing.B) { var items [1024]Item for i := 0; i < b.N; i++ { var tmp int for k := range items { tmp = items[k].id } _ = tmp } }
funcBenchmarkRangeStruct(b *testing.B) { var items [1024]Item for i := 0; i < b.N; i++ { var tmp int for _, item := range items { tmp = item.id } _ = tmp } }
差距大概50倍。 原因是for range的k,v中的v是复制的,需要申请内存(除非值为指针)。 for range尽量只使用下标,不使用值。
any 传入 []any或map[string]any
1 2 3 4 5 6 7 8 9 10 11 12 13
v := reflect.ValueOf(i) switch v.Kind() { case reflect.Slice: items := make([]any, v.Len()) for i := 0; i < v.Len(); i++ { items[i] = v.Index(i).Interface() } case reflect.Map: items := make(map[string]any) for _, key := range v.MapKeys() { items[key.String()] = v.MapIndex(key).Interface() } }
string
for idx & for range
1 2 3 4 5 6 7 8 9 10 11 12
a := "1万🔖" for i := 0; i < len(a); i++ { println(i, a[i]) } println() for i := range a { fmt.Println(i, a[i]) } println() for i, v := range a { fmt.Println(i, v) }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 49 1 228 2 184 3 135 4 240 5 159 6 148 7 150
0 49 1 228 4 240
0 49 1 19975 4 128278
拼接
多次拼接使用strings.Builder
1 2 3 4 5 6 7 8 9 10 11
funcbuilderConcat(strs... string)string { var builder strings.Builder for _, str := range strs { builder.Grow(len(str)) } for _, str := range strs { builder.WriteString(str) } return builder.String() }