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

简介

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

  • for 索引 += 的方式

  • for range += 的方式

  • strings.Join 的方式

  • strings.Builder 的方式

写一个基准测试文件

echo_bench_test.go

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
}

运行基准测试

shell 复制代码
go test -bench=. -benchmem

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

yaml 复制代码
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 核)
500000 b.N 的值,代表该函数跑了 50 万次
3500 ns/op 每次调用耗时 3500 纳秒
120 B/op 每次操作分配的字节数(字节越少越好)
5 allocs/op 每次操作的内存分配次数(次数越少越好)

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

方法 ns/op B/op allocs/op 说明
EchoAll1 3500 ns 120 B 5 += 每次创建新字符串,开销大
EchoAll2 2400 ns 104 B 4 range + +=,仍然多次内存分配
EchoAll3 1600 ns 80 B 2 Join 比较高效
EchoAll4 800 ns 32 B 1 strings.Builder 最优
相关推荐
极限实验室15 分钟前
Operator 开发入门系列(一):Hello World
go
纪元A梦13 小时前
华为OD机试真题——跳格子3(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
Bohemian14 小时前
浅谈Golang逃逸分析
后端·面试·go
栩栩云生15 小时前
📥 x-cmd install | Pathos - 告别混乱!你的终端 $PATH 环境变量管理神器
go·命令行
航哥16 小时前
Go语言编译器的正确打开方式(一)- 从源码编译 go
go·编译器
楽码1 天前
一文看懂!编程语言访问变量指针和复制值
后端·go·编程语言
forever231 天前
单个服务添加 OpenTelemetry (otel)
go
来杯咖啡1 天前
Golang 事务消息队列:基于 SQLite 的轻量级消息队列解决方案
后端·go
十分钟空间1 天前
Go语言实现权重抽奖系统
后端·go
DemonAvenger1 天前
Go并发编程进阶:基于Channel的并发控制模式实战指南
分布式·架构·go