Costura de cuerdas de Golang y optimización del generador

Visión de conjunto

  • + Costuras de números
  • costuras fmt
  • Unir costuras
  • costuras de amortiguación
  • costuras de constructor

En el caso de menos datos, estos métodos no son muy diferentes, pero se recomienda su uso cuando hay muchas cadenas para unir builder. La conexión de signo + es adecuada para la concatenación de cadenas cortas y constantes, ya que el compilador optimizará

+ Costuras de números

s := s1+s2+s3

costuras fmt

s := fmt.Sprintf("%v%v",s1,s2)

Unir costuras

Reciba una serie de cadenas y conviértalas en una cadena concatenada

sList := []string{s1,s2}
s := strings.Join(SList,"") 

costuras de amortiguación

No solo puede concatenar cadenas de caracteres, sino también concatenar bytes, etc.

var b = bytes.Buffer
b.WriteString(s1)
b.WriteString(S2)
s := String() 

costuras de constructor

var b strings.Builder
b.WriteString(s1)
b.WriteString(s2)
s := b.String()

Optimizar el constructor

Código de prueba

proyecto \ stringBuilder \ sb.go

package stringBuilder

import "strings"

func StringBuilder(p []string) string {
	var b strings.Builder
	l:=len(p)
	for i:=0;i<l;i++{
		b.WriteString(p[i])
	}
	return b.String()
}


proyecto \ stringBuilder \ sb_test.go

package stringBuilder

import "testing"

const TESTSTRING  = "test,"

/*
	初始化函数
	生成一个具有N个字符串的数组
*/

func initStrings(N int) []string{
	s:=make([]string,N)
	for i:=0;i<N;i++{
		s[i]=TESTSTRING
	}
	return s;
}

/*
	测试
	10个字符串
*/
func BenchmarkStringBuilder10(b *testing.B) {
	p:= initStrings(10)
	b.ResetTimer()
	for i:=0;i<b.N;i++{
		StringBuilder(p)
	}
}

/*
	测试
	100个字符串
*/
func BenchmarkStringBuilder100(b *testing.B) {
	p:= initStrings(100)
	b.ResetTimer()
	for i:=0;i<b.N;i++{
		StringBuilder(p)
	}
}
/*
	测试
	1000个字符串
*/
func BenchmarkStringBuilder1000(b *testing.B) {
	p:= initStrings(1000)
	b.ResetTimer()
	for i:=0;i<b.N;i++{
		StringBuilder(p)
	}
}


Resultado de la prueba

goos: windows
goarch: amd64
pkg: TestProject/stringBuilder
BenchmarkStringBuilder10-4   5163981    228 ns/op      120 B/op       4 allocs/op
BenchmarkStringBuilder100-4  1000000    1150 ns/op     1016 B/op      7 allocs/op
BenchmarkStringBuilder1000-4 107428     11735 ns/op    21240 B/op     13 allocs/op
PASS

builderDonde es lento

Como se puede ver en los resultados de la evaluación comparativa, se ralentiza principalmente en asignaciones de memoria múltiples.Si las asignaciones de memoria múltiples causan GC, ¡será más lento!

builder Código fuente

// WriteString appends the contents of s to b's buffer.
// It returns the length of s and a nil error.
func (b *Builder) WriteString(s string) (int, error) {
	b.copyCheck()
	b.buf = append(b.buf, s...)
	return len(s), nil
}

En pocas palabras, se rellena con appendfunciones []byte b: cuando bse expande la matriz de bytes, causará la asignación de memoria, lo que hace que la operación sea más lenta.

Solución

Reduzca la cantidad de asignaciones de memoria, que es b字节数组asignar el tamaño de antemanocap

Modifica el código

func StringBuilder(p []string,cap int) string {
	var b strings.Builder
	l:=len(p)
	b.Grow(cap)
	for i:=0;i<l;i++{
		b.WriteString(p[i])
	}
	return b.String()
}
//测试代码以10个字符串为例
//修改为如下
func BenchmarkStringBuilder10(b *testing.B) {
	p:= initStrings(10)
	b.ResetTimer()
	cap := 10*len(TESTSTRING)
	for i:=0;i<b.N;i++{
		StringBuilder(p,cap)
	}
}

Resultados de la prueba después de la optimización

BenchmarkStringBuilder10-4   10027047    114 ns/op    64 B/op    1 allocs/op
BenchmarkStringBuilder100-4  1312066     810 ns/op    512 B/op   1 allocs/op
BenchmarkStringBuilder1000-4  141570     8080 ns/op   5376 B/op   1 allocs/op
PASS

Puede ser optimizado 20%~50%

Supongo que te gusta

Origin www.cnblogs.com/Jun10ng/p/12682524.html
Recomendado
Clasificación