【发布时间】:2020-06-26 12:29:45
【问题描述】:
我正在尝试找出 strings.Join 方法 与 += 的常规连接的用法。
对于这个比较,我在 os.Args 上使用这两种方法作为要连接的字符串列表。
我的连接函数代码是:
func regular_concatenation() {
var s, sep string
for i := 1; i < len(os.Args); i++ {
s += sep + os.Args[i]
sep = " "
}
fmt.Println(s)
}
func join_concatenation() {
fmt.Println(strings.Join(os.Args, " "))
}
而性能检查的主要功能是:
func main() {
var end_1, end_2 float64
var start_1, start_2 time.Time
start_1 = time.Now()
for i:=0; i < 100; i++ {
ex1_3_join_concatenation()
}
end_1 = time.Since(start_1).Seconds()
start_2 = time.Now()
for i:=0; i < 100; i++ {
ex1_3_regular_concatenation()
}
end_2 = time.Since(start_2).Seconds()
fmt.Println(end_1)
fmt.Println(end_2)
}
问题是 - 当我运行代码时,比如使用 20 个参数 (os.Args),我得到的结果是 strings.Join 方法比常规连接慢。
这让我很困惑,因为我理解它的方式 - 当使用常规 += 方法时,它每次都会创建一个新的字符串引用(因为字符串在 golang 中是不可变的),因此垃圾收集器应该按顺序运行收集未使用的数据,这很浪费时间。
所以问题是 - strings.Join 真的是更快的方法吗?如果是 - 在这个例子中我做错了什么?
【问题讨论】:
-
从创建一个真实的、独立的基准开始;糟糕的基准会产生糟糕的结果。如果没有其他混淆变量,join 方法将具有更少的分配,并且会更快。您的
join函数还处理一个比另一个多的参数。 -
你必须在谷歌上搜索有关如何对 go 代码进行基准测试的信息,我认为这里没什么好讨论的
-
好吧,我建议你问这个基准有什么问题。因为你的简单问题有一个简单的答案,
strings.Join比字符串连接更快。 -
一个不同之处可能是您在第二个基准测试中添加了 os.Args[0]。
-
尝试使用包含 1000 个左右元素的数组代替 os.Args,您会发现 strings.Join 每次都更快。
标签: performance go garbage-collection