- 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.
1 2 3 4 5 6 7 8 | <span class="token keyword">func</span> <span class="token function">Concat</span><span class="token punctuation">(</span>values <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span> s <span class="token operator">:=</span> <span class="token string">""</span> <span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> value <span class="token operator">:=</span> <span class="token keyword">range</span> values <span class="token punctuation">{</span> s <span class="token operator">+=</span> value <span class="token punctuation">}</span> <span class="token keyword">return</span> s <span class="token punctuation">}</span> |
- 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
1 2 3 4 5 6 7 8 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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:
1 2 | go test -bench=. |
1 | go test -bench=. -benchmem |