欢迎来到徐庆高(Tea)的个人博客网站
磨难很爱我,一度将我连根拔起。从惊慌失措到心力交瘁,我孤身一人,但并不孤独无依。依赖那些依赖我的人,信任那些信任我的人,帮助那些给予我帮助的人。如果我愿意,可以分裂成无数面镜子,让他们看见我,就像看见自己。察言观色和模仿学习是我的领域。像每个深受创伤的人那样,最终,我学会了随遇而安。
当前位置: 日志文章 > 详细内容

Go语言中字符串四种拼接方式的性能对比

2025年04月24日 Golang
简介使用完整的基准测试代码文件,可以直接运行来比较四种字符串拼接方法的性能。for 索引 += 的方式for range += 的方式strings.join 的方式strings.builder 的

简介

使用完整的基准测试代码文件,可以直接运行来比较四种字符串拼接方法的性能。

  • for 索引 += 的方式
  • for range += 的方式
  • strings.join 的方式
  • strings.builder 的方式

写一个基准测试文件

echo_bench_test.go

package main

import (
	"os"
	"strings"
	"testing"
)

func echoall1() string {
	var s, sep string
	for i := 0; i < len(os.args); i++ {
		s += sep + os.args[i]
		sep = " "
	}
	return s
}

func echoall2() string {
	s, sep := "", ""
	for _, arg := range os.args[:] {
		s += sep + arg
		sep = " | "
	}
	return s
}

func echoall3() string {
	return strings.join(os.args[:], " , ")
}

// strings.builder 是 go 推荐的高效字符串拼接方式,尤其在循环中拼接时,
// 可以减少内存分配。


func echoall4() string {
	var builder strings.builder
	for i, arg := range os.args[:] {
		if i > 0 {
			builder.writestring(" <> ")
		}
		builder.writestring(arg)
	}
	return builder.string()
}


// ===== benchmark functions =====

func benchmarkechoall1(b *testing.b) {
	// 模拟更长参数列表,避免误差过大
	originalargs := os.args
	os.args = make([]string, 100)
	for i := range os.args {
		os.args[i] = "arg"
	}

	b.resettimer()
	for i := 0; i < b.n; i++ {
		_ = echoall1()
	}
	os.args = originalargs // 恢复
}

func benchmarkechoall2(b *testing.b) {
	originalargs := os.args
	os.args = make([]string, 100)
	for i := range os.args {
		os.args[i] = "arg"
	}

	b.resettimer()
	for i := 0; i < b.n; i++ {
		_ = echoall2()
	}
	os.args = originalargs
}

func benchmarkechoall3(b *testing.b) {
	originalargs := os.args
	os.args = make([]string, 100)
	for i := range os.args {
		os.args[i] = "arg"
	}

	b.resettimer()
	for i := 0; i < b.n; i++ {
		_ = echoall3()
	}
	os.args = originalargs
}

func benchmarkechoall4(b *testing.b) {
	originalargs := os.args
	os.args = make([]string, 100)
	for i := range os.args {
		os.args[i] = "arg"
	}

	b.resettimer()
	for i := 0; i < b.n; i++ {
		_ = echoall4()
	}
	os.args = originalargs
}

运行基准测试

go test -bench=. -benchmem

示例输出结果(不同机器会略有不同):

goos: darwin
goarch: amd64
pkg: example
benchmarkechoall1-8     500000     3500 ns/op     120 b/op     5 allocs/op
benchmarkechoall2-8     700000     2400 ns/op     104 b/op     4 allocs/op
benchmarkechoall3-8    1000000     1600 ns/op      80 b/op     2 allocs/op
benchmarkechoall4-8    2000000      800 ns/op      32 b/op     1 allocs/op

pass
ok      example    3.456s

每一行含义:

字段含义
benchmarkechoall1测试函数名
-8使用的 cpu 线程数(8 核)
500000b.n 的值,代表该函数跑了 50 万次
3500 ns/op每次调用耗时 3500 纳秒
120 b/op每次操作分配的字节数(字节越少越好)
5 allocs/op每次操作的内存分配次数(次数越少越好)

go 的基准测试自动决定运行次数(b.n),直到结果足够稳定。

方法ns/opb/opallocs/op说明
echoall13500 ns120 b5+= 每次创建新字符串,开销大
echoall22400 ns104 b4range + +=,仍然多次内存分配
echoall31600 ns80 b2join 比较高效
echoall4800 ns32 b1strings.builder 最优

到此这篇关于go语言中字符串四种拼接方式的性能对比的文章就介绍到这了,更多相关go字符串拼接内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!