- Bài viết này để giúp việc viết
function
nối stringarray string
->string
một cách tối ưu nhất. - Thông thường khi viết một function để chuyển đổi từ
array string
sang mộtstring
thì đa số anh/em devgolang
sẽ viết.
func Concat(values []string) string { s := "" for _, value := range values { s += value } return s
}
- Cách viết không tối ưu, trong
golang
khi nối chuỗi sẽ không dùng lại biếns
mà luôn tạo ra một vùng nhớ mới trên memory. - Để tối ưu, có 2 cách viết mẫu:
Cách 1
func Concatv2(values []string) string { sb := strings.Builder{} // (1) for _, value := range values { _, _ = sb.WriteString(value) // (2) } return sb.String() // (3)
}
- (1): tạo một
strings.Builder
- (2): nối chuỗi
- (3): trả về kết quả
Cách 2
func Concatv3(values []string) string { total := 0 for i := 0; i < len(values); i++ { // (1) total += len(values[i]) } sb := strings.Builder{} sb.Grow(total) // (2) for _, value := range values { _, _ = sb.WriteString(value) } return sb.String()
}
- (1): vòng lặp mỗi
string
để đếm tổng sốbytes
. - (2): tạo capacity,
Grow
có thể bịpanics
, cẩn thận khi sài.
Benchmark
- tạo file
main_test.go
, copy code dưới đây.
package main import "testing" var strs = []string{"b111231sdfsdfsaf21312sdafsda", "b111231sdfsdfsaf21312sdafsda", "b111231sdfsdfsaf21312sdafsda", "b111231sdfsdfsaf21312sdafsda"} func BenchmarkV1(b *testing.B) { for i := 0; i < b.N; i++ { Concat(strs) }
} func BenchmarkV2(b *testing.B) { for i := 0; i < b.N; i++ { Concatv2(strs) }
} func BenchmarkV3(b *testing.B) { for i := 0; i < b.N; i++ { Concatv3(strs) }
}
- thực hiện câu lệnh:
go test -bench=.
go test -bench=. -benchmem