+1

[Golang] Concatenation Strings

  • Bài viết này để giúp việc viết function nối string array 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ột string thì đa số anh/em dev golang 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ến s 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


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí