这是一个使用闭包的真实、简单且DRY Go 基准测试。我想知道各种Substr
函数的性能如何随着子字符串的大小(hi
- lo
)而变化。
package main
import (
"fmt"
"strings"
"testing"
)
func Substr1(str string, lo, hi int) string {
return string([]byte(str[lo:hi]))
}
func Substr2(str string, lo, hi int) string {
sub := str[lo:hi]
return (sub + " ")[:len(sub)]
}
func Substr3(str string, lo, hi int) string {
sub := str[lo:hi]
if len(sub) == 0 {
return ""
}
return sub[0:1] + sub[1:]
}
var substrFunctions = []struct {
name string
function func(str string, lo, hi int) string
}{
{"Substr1", Substr1},
{"Substr2", Substr2},
{"Substr3", Substr3},
}
var substrBenchmarks = []struct {
name string
strLen, subLo, subHi int
}{
{"Zero ", 1, 1, 1},
{"Small ", 4, 1, 4},
{"Medium", 256, 1, 256},
{"Large ", 4096, 1, 4096},
}
func BenchmarkSubstrSize() {
fmt.Println("BenchmarkSubstrSize:")
for _, benchmark := range substrBenchmarks {
str := strings.Repeat("abc", benchmark.strLen)
for _, function := range substrFunctions {
benchmarkFunc := func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
function.function(str, benchmark.subLo, benchmark.subHi)
}
b.StopTimer()
}
results := testing.Benchmark(benchmarkFunc)
fmt.Println(benchmark.name, function.name, results)
}
}
}
func main() {
BenchmarkSubstrSize()
}
输出:
BenchmarkSubstrSize:
Zero Substr1 50000000 54.8 ns/op
Zero Substr2 100000000 19.6 ns/op
Zero Substr3 500000000 6.66 ns/op
Small Substr1 20000000 95.7 ns/op
Small Substr2 50000000 70.4 ns/op
Small Substr3 50000000 70.1 ns/op
Medium Substr1 5000000 380 ns/op
Medium Substr2 10000000 229 ns/op
Medium Substr3 10000000 213 ns/op
Large Substr1 500000 4290 ns/op
Large Substr2 1000000 2007 ns/op
Large Substr3 1000000 2275 ns/op