package split
import"strings"// 定义一个切割字符串的包// Split 按照 sep 分割 s, a:b:c --> a b cfuncSplit(s, sep string)[]string{// 得到字符串中分隔符的数量
sepNum := strings.Count(s, sep)// 按照分隔符数量申请内存
r :=make([]string,0, sepNum+1)
index := strings.Index(s, sep)for index >=0{
r =append(r, s[:index])
s = s[index+len(sep):]
index = strings.Index(s, sep)}
r =append(r, s)return r
}
split_test.go
package split
import("fmt""os""reflect""testing")// 子测试集funcTestNormalSplit(t *testing.T){
get :=Split("a:b:c",":")
want :=[]string{"a","b","c"}if ok := reflect.DeepEqual(get, want);!ok {
t.Fatalf("期望结果: %v, 实际结果: %v\n", want, get)}}funcTestMultiSplit(t *testing.T){// 这里是 setup 和 teardown 的使用实例
f :=setupT(t)deferf(t)
get :=Split("a::b::c","::")
want :=[]string{"a","b","c"}if ok := reflect.DeepEqual(get, want);!ok {
t.Fatalf("期望结果: %v, 实际结果: %v\n", want, get)}else{
t.Log("pass test...")}}funcTestNumSplit(t *testing.T){
get :=Split("1231","1")
want :=[]string{"","23",""}if ok := reflect.DeepEqual(get, want);!ok {
t.Fatalf("期望结果: %v, 实际结果: %v\n", want, get)}}// 子测试组funcTestSplitGroup(t *testing.T){// 存放测试的结构体type test struct{
str string
sep string
want []string}// 将测试用例都实例化到 map 中
items :=map[string]test{"normal": test{
str:"a:b:c",
sep:":",
want:[]string{"a","b","c"},},"multi": test{
str:"a::b::c",
sep:"::",
want:[]string{"a","b","c"},},"num": test{
str:"1231",
sep:"1",
want:[]string{"","23",""},},}for k, i :=range items {
t.Run(k,func(t *testing.T){
get :=Split(i.str, i.sep)if ok := reflect.DeepEqual(i.want, get);!ok {
t.Fatalf("测试关键字: %v, 期望结果: %v, 实际结果: %v\n", k, i.want, get)}})}}// 性能测试 - 基础版funcBenchmarkSplit(b *testing.B){for i :=0; i < b.N; i++{Split("a:b:c",":")}}// 性能测试 - 并发版funcBenchmarkParallelSplit(b *testing.B){// 设置 cpu 数量// b.SetParallelism(1)
b.RunParallel(func(pb *testing.PB){for pb.Next(){Split("1231","1")}})}// 在全局加前后操作funcTestMain(m *testing.M){
fmt.Println("start test...")
r := m.Run()
fmt.Println("end test...")
os.Exit(r)}// 给单一测试用例加前后操作, 如果是性能测试, t 改 b 即可funcsetupT(t *testing.T)func(t *testing.T){
t.Log("start test...")// 测试前执行returnfunc(t *testing.T){// 返回函数名, 使用时 defer 调用
t.Log("end test...")}}
fib.go
package fib
// Fib 计算斐波那契数列funcFib(n int)int{if n <2{return n
}returnFib(n-1)+Fib(n-2)}
fib_test.go
package fib
import"testing"// 性能测试 - 性能对比, 根据数据量不同进行分析funcbenchmarkFib(b *testing.B, n int){// 清除耗时// b.ResetTimer()for i :=0; i < b.N; i++{Fib(n)}}funcBenchmarkFib2(b *testing.B){benchmarkFib(b,2)}funcBenchmarkFib10(b *testing.B){benchmarkFib(b,10)}funcBenchmarkFib20(b *testing.B){benchmarkFib(b,20)}
运行结果
split code
xxx@xxx split % go test -v
testMain start test...
=== RUN TestNormalSplit
--- PASS: TestNormalSplit (0.00s)=== RUN TestMultiSplit
--- PASS: TestMultiSplit (0.00s)
split_test.go:111: setupT start test...
split_test.go:30: pass test...
split_test.go:113: setupT end test...
=== RUN TestNumSplit
--- PASS: TestNumSplit (0.00s)=== RUN TestSplitGroup
=== RUN TestSplitGroup/normal
=== RUN TestSplitGroup/multi
=== RUN TestSplitGroup/num
--- PASS: TestSplitGroup (0.00s)
--- PASS: TestSplitGroup/normal (0.00s)
--- PASS: TestSplitGroup/multi (0.00s)
--- PASS: TestSplitGroup/num (0.00s)
PASS
testMain end test...
ok xxx/split 0.013s
fib code
xxx@xxx Fib % go test -bench=. -v
goos: darwin
goarch: amd64
pkg: code.oldboy.com/Fib
BenchmarkFib2-4 100000000 10.9 ns/op
BenchmarkFib10-4 2000000 695 ns/op
BenchmarkFib20-4 20000 90912 ns/op
PASS
ok xxx/Fib 5.728s