古老的榕树

Go bytes.Buffer 和 strings.Builder 性能比较

潘军杰 发表于 2018-03-18 21:36 阅读(9153) 评论(0) 赞(0)
Go 语言里字符拼接是常用到的,而且只是进行少量的字符串拼接,这次专门根据这个场景进行做基准测试,具体代码如下,如果测试方法有什么欠妥的地方,还请读者提出来。本次测试力求测试的公平性。

测试目标方法代码:

/**  strbyt.go
package src

import("bytes""fmt""strings")

func AppendWithAdd() {
	var s string
	for i: =0; i < 10; i++{
		s = s + "string"
	}
}

func AppendWithSprintf() {
	var s string
	for i: =0; i < 10; i++{
		s = fmt.Sprintf("%s%s", s, "string")
	}
}

func AppendWithBytesBuffer() {
	var byt bytes.Buffer
	for i: =0; i < 10; i++{
		byt.WriteString("string")
	}
	byt.String()
}

func AppendWithStringBuilder() {
	var sbuilder strings.Builder
	for i: =0; i < 10; i++{
		sbuilder.WriteString("string")
	}
	sbuilder.String()
}
**/

基准测试代码:
/**  strbyt_test.go
package src

import("testing")

func Benchmark_AppendWithAdd(b * testing.B) {
	for i: =0; i < b.N; i++{
		AppendWithAdd()
	}
}

func Benchmark_AppendWithSprintf(b * testing.B) {
	for i: =0; i < b.N; i++{
		AppendWithSprintf()
	}
}

func Benchmark_AppendWithBytesBuffer(b * testing.B) {
	for i: =0; i < b.N; i++{
		AppendWithBytesBuffer()
	}
}

func Benchmark_AppendWithStringBuilder(b * testing.B) {
	for i: =0; i < b.N; i++{
		AppendWithStringBuilder()
	}
}
**/


执行测试:
cd /usr/local/GOPATH/src/folder/
go test -test.bench=.* -count=5

测试结果打印如下:
goos: linux
goarch: amd64
pkg: folder
Benchmark_AppendWithAdd-2              3000000        490 ns/op
Benchmark_AppendWithAdd-2              3000000        489 ns/op
Benchmark_AppendWithAdd-2              3000000        673 ns/op
Benchmark_AppendWithAdd-2              2000000        754 ns/op
Benchmark_AppendWithAdd-2              3000000        491 ns/op
Benchmark_AppendWithSprintf-2          1000000       1443 ns/op
Benchmark_AppendWithSprintf-2          1000000       1451 ns/op
Benchmark_AppendWithSprintf-2          1000000       1451 ns/op
Benchmark_AppendWithSprintf-2          1000000       1445 ns/op
Benchmark_AppendWithSprintf-2          1000000       1445 ns/op
Benchmark_AppendWithBytesBuffer-2      10000000        184 ns/op
Benchmark_AppendWithBytesBuffer-2      10000000        184 ns/op
Benchmark_AppendWithBytesBuffer-2      10000000        184 ns/op
Benchmark_AppendWithBytesBuffer-2      10000000        184 ns/op
Benchmark_AppendWithBytesBuffer-2      10000000        184 ns/op
Benchmark_AppendWithStringBuilder-2    10000000        231 ns/op
Benchmark_AppendWithStringBuilder-2    10000000        232 ns/op
Benchmark_AppendWithStringBuilder-2    10000000        232 ns/op
Benchmark_AppendWithStringBuilder-2    10000000        232 ns/op
Benchmark_AppendWithStringBuilder-2    10000000        231 ns/op
PASS
ok  folder 41.089s


从测试结果来看,性能从高到低排序如下:
bytes.Buffer > strings.Builder > string + string > fmt.Sprintf 

这次测试的背景是 Go 1.9 版本后,strings 包刚刚增加了 strings.Builder,本人特意看了源码的实现,发现它是非线程安全的,并好奇它和 bytes.Buffer 的性能,特别测试一番,结果两者的性能很接近,在一个水平上。


另外本人针对大量字符串拼接的情况也做了测试,发现 strings.Builder 以微弱的优势胜出了,不过日常我们很少用到大量的字符串拼接的情况。

大量字符串拼接测试结果:
goos: linux
goarch: amd64
pkg: folder
Benchmark_AppendWithAdd-2                     1 4557618695 ns/op
Benchmark_AppendWithAdd-2                     1 4545522179 ns/op
Benchmark_AppendWithAdd-2                     1 4547196905 ns/op
Benchmark_AppendWithAdd-2                     1 4570965126 ns/op
Benchmark_AppendWithAdd-2                     1 4561951695 ns/op
Benchmark_AppendWithSprintf-2                 1 7634729506 ns/op
Benchmark_AppendWithSprintf-2                 1 6052255032 ns/op
Benchmark_AppendWithSprintf-2                 1 5795376326 ns/op
Benchmark_AppendWithSprintf-2                 1 5823858295 ns/op
Benchmark_AppendWithSprintf-2                 1 5829590737 ns/op
Benchmark_AppendWithBytesBuffer-2          1000    1515946 ns/op
Benchmark_AppendWithBytesBuffer-2          1000    1513585 ns/op
Benchmark_AppendWithBytesBuffer-2          1000    1513932 ns/op
Benchmark_AppendWithBytesBuffer-2          1000    1515592 ns/op
Benchmark_AppendWithBytesBuffer-2          1000    1519741 ns/op
Benchmark_AppendWithStringBuilder-2        1000    1395933 ns/op
Benchmark_AppendWithStringBuilder-2        1000    1390083 ns/op
Benchmark_AppendWithStringBuilder-2        1000    1391791 ns/op
Benchmark_AppendWithStringBuilder-2        1000    1388121 ns/op
Benchmark_AppendWithStringBuilder-2        1000    1388763 ns/op
PASS
ok  folder 69.930s


0 条网友评论

哇~~~ 竟然还没有评论!

称呼*
邮箱*
内容*
验证码*
验证码 看不清换张