Go语言并发之道学习五 channel生成器单元测试

channel生成器单元测试

go test 命令,会自动读取源码目录下面名为 *_test.go 的文件,生成并运行测试用的可执行文件。

新建一个 repeat_test.go 的文件:

package main

import "testing"


func BenchmarkGeneric(b *testing.B)  {
	repeat := func(
		done <- chan interface{},
		values ...interface{},
		)<-chan interface{}{
		stringStream := make(chan interface{})
		go func() {
			defer close(stringStream)
			for{
				for _,v := range values {
					select {
					case <- done:
						return
					case stringStream<-v:
					}
				}
			}
		}()
		return stringStream
	}
	token := func(
		done <-chan interface{},
		valueStream <-chan interface{},
		num int,
		) <-chan interface{}{
		tokenStream := make(chan interface{})
		go func() {
			defer close(tokenStream)
			for i := num;i > 0||i == -1;{
				if i != -1{
					i--
				}
				select {
				case <-done:
					return
				case tokenStream<-<-valueStream:
				}
			}
		}()
		return tokenStream
	}
	toString := func(
		done <-chan interface{},
		valueStream <-chan interface{},
		) <- chan string{
		stringStream := make(chan string)
		go func() {
			defer close(stringStream)
			for v := range valueStream{
				select {
				case <-done:
					return
				case stringStream<-v.(string):
				}
			}
		}()
		return stringStream
	}
	done := make(chan interface{})
	defer close(done)

	b.ResetTimer()
	for range toString(done,token(done,repeat(done,"a"),b.N)){

	}
}

func BenchmarkTyped(b *testing.B){
	repeat := func(
		done <-chan interface{},
		values ...string,
		) <-chan string {
		valueStream := make(chan string)
		go func() {
			defer close(valueStream)
			for {
				for _,v := range values{
					select {
					case <-done:
						return
					case valueStream<-v:
					}
				}
			}
		}()
		return valueStream
	}

	take := func(
		done <-chan interface{},
		valueStream <-chan string,
		num int,
		)<-chan string {
		takeStream := make(chan string)
		go func() {
			defer close(takeStream)
			for i:=num;i>0||i == -1; {
				if i != -1{
					i--
				}
				select {
				case <-done:
					return
				case takeStream<-<-valueStream:
				}
			}
		}()
		return takeStream
	}

	done := make(chan interface{})
	defer close(done)

	b.ResetTimer()
	for range take(done,repeat(done,"a"),b.N)  {

	}
}

 

运行测试

# 测试所有函数
[root@izj6c4jirdug8kh3uo6rdez goroutine]# go test -v -bench=. -benchmem repeat_test.go
goos: linux
goarch: amd64
BenchmarkGeneric 	 1000000	      1245 ns/op	       0 B/op	       0 allocs/op
BenchmarkTyped   	 2000000	       793 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	command-line-arguments	3.662s


# 测试 BenchmarkTyped 函数
[root@izj6c4jirdug8kh3uo6rdez goroutine]# go test -v -bench=Typed -benchmem repeat_test.go
goos: linux
goarch: amd64
BenchmarkTyped 	 2000000	       762 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	command-line-arguments	2.301s
----------------------------------
go test 命令常用的参数:
-bench regexp 执行相应的 benchmarks,例如 -bench=.
-cover 开启测试覆盖率
-run regexp 只运行 regexp 匹配的函数,例如 -run=Array 那么就执行包含有 Array 开头的函数
-v 显示测试的详细命令

注意:Windows 下使用 go test 命令行时,-bench=.应写为-bench="."。

-----------------------------------
go test 结果:

$ go test -v -bench=.  -benchmem benchmark_test.go
----------------------------------------------------
goos: linux
goarch: amd64
Benchmark_Add-4           20000000         0.33 ns/op        16 B/op     2 allocs/op 
PASS
ok          command-line-arguments        0.700s
------------------------------------------------------

第 4 行中显示基准测试名称,
2000000000 表示测试的次数,也就是 testing.B 结构中提供给程序使用的 N。
0.33 ns/op 表示每一个操作耗费多少时间(纳秒)。
16 B/op 表示每一次调用需要分配 16 个字节,
2 allocs/op 表示每一次调用有两次分配。

第 5 行中
0.700s 表示程序运行花费的时间

参考:http://c.biancheng.net/view/124.html 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值