Golang内置了单元测试的库testing
,利用该库可以进行单元测试。
对于一个可被testing库测试的源文件有两点要求:
test
结尾,比如hello_test.go
单元测试的函数名字要以Test
开头,函数参数必须是t *testing.T
, 比如func TestHello(t *testing.T){}
,如下是要被测试的代码:
// hello_test.gopackage hello_testimport "testing"func TestHello(t *testing.T) { t.Log("hello")}
然后输入go test 包名 -v 函数名
,
比如:go test hello_test -v TestHello
就会执行想要测试的函数,对于上述的hello_test.go
,在控制台会输出下面结果:
图中画红线的部分就是代码中输出语句的结果。2. 求数组中最大的子数组之和
题目:
求数组中的子数组中和最大的子数组。
比如数组[-3, -4, 5, -3, -1]
最大子数组是[5]
。
比如数组[-3, 5, -1, 6, -4]
最大子数组是[5, -1, 6]
.
分析:
对于这道题,求子数组,那么就是原数组中连续的若干个元素组成的数组,第一反应想到双指针解法,虽然不是最优的。
对于双指针解法,代码如下:
// max_subarray_test.gopackage max_subarray_testimport "testing"// 数组求和函数func sum(nums []int) int { sum := 0 for _, num := range nums { sum += num } return sum}// 求一个数组的最大子数组// 本方案时间复杂度O(N^2)func maxSubarr(arr []int) (int, []int) { inputArr := arr maxSubarr := inputArr[:] leftIndex := 0 rightIndex := len(inputArr) - 1 max := inputArr[0] // 双指针法,从两侧向中间逼近 for leftIndex <= rightIndex { // 如果在某个范围,子数组的和比最大值大,那么保存当前子数组和最大值 temp := sum(inputArr[leftIndex : rightIndex+1]) if temp > max { max = temp maxSubarr = inputArr[leftIndex : rightIndex+1] } // 如果该子数组只剩下一个元素了,直接返回 if len(maxSubarr) <= 1 { break } // 继续向中间逼近,看左边和右边的数哪个数小,小的向中间走 if inputArr[leftIndex] < inputArr[rightIndex] { leftIndex++ } else { rightIndex-- } } return max, maxSubarr}func TestMaxSubarray(t *testing.T) { inputArr := []int{-2, -3, -5, -1, -9} max, subarr := maxSubarr(inputArr) t.Logf("输入的数组:%v,最大子数组:%v,最大值:%v", inputArr, max, subarr) inputArr = []int{-2, 4, -3, 6, -9} max, subarr = maxSubarr(inputArr) t.Logf("输入的数组:%v,最大子数组:%v,最大值:%v", inputArr, max, subarr)}
输入命令:
go test max_subarray_test.go -v TestMaxSubarray
显示如下结果:
Golang自带了性能分析工具pprof
,可以记录在程序运行过程中cpu和内存的使用情况。
这里就测试上述的“求数组中最大子数组”的代码,测试如下:
// max_subarray.gopackage mainimport ( "flag" "fmt" "log" "os" "runtime" "runtime/pprof")// 数组求和函数func sum(nums []int) int { sum := 0 for _, num := range nums { sum += num } return sum}// 求一个数组的最大子数组// 本方案时间复杂度O(N^2)func maxSubarr(arr []int) (int, []int) { inputArr := arr maxSubarr := inputArr[:] leftIndex := 0 rightIndex := len(inputArr) - 1 max := inputArr[0] // 双指针法,从两侧向中间逼近 for leftIndex <= rightIndex { // 如果在某个范围,子数组的和比最大值大,那么保存当前子数组和最大值 temp := sum(inputArr[leftIndex : rightIndex+1]) if temp > max { max = temp maxSubarr = inputArr[leftIndex : rightIndex+1] } // 如果该子数组只剩下一个元素了,直接返回 if len(maxSubarr) <= 1 { break } // 继续向中间逼近,看左边和右边的数哪个数小,小的向中间走 if inputArr[leftIndex] < inputArr[rightIndex] { leftIndex++ } else { rightIndex-- } } return max, maxSubarr}func contentTesting() { for i := 0; i < 10000; i++ { inputArr := []int{-2, -3, -5, -1, -9} max, subarr := maxSubarr(inputArr) fmt.Printf("输入的数组:%v,最大子数组:%v,最大值:%v\n", inputArr, max, subarr) }}var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")var memprofile = flag.String("memprofile", "", "write memory profile to `file`")func main() { flag.Parse() if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal("Could not create cpu profile: ", err) } defer f.Close() // error handling omitted for example if err := pprof.StartcpuProfile(f); err != nil { log.Fatal("Could not start cpu profile: ", err) } defer pprof.StopcpuProfile() contentTesting() } contentTesting() if *memprofile != "" { f, err := os.Create(*memprofile) if err != nil { log.Fatal("Could not create memory profile: ", err) } defer f.Close() // error handling omitted for example runtime.GC() // get up-to-date statistics if err := pprof.WriteHeapProfile(f); err != nil { log.Fatal("Could not write memory profile: ", err) } contentTesting() }}
然后编译上述源文件:
go build max_subarray.go
会生成可执行文件max_subarray
,然后执行该可执行文件,输入参数,表示输出cpu信息:
./max_subarray --cpuprofile=cpu.pprof
此时会生成名称为cpu.pprof
的二进制文件,无法直接打开,需要使用golang的too工具下的pprof打开它:
go tool pprof cpu.pprof
可以看到cpu在程序执行过程中的信息:
也可以以生成函数调用图,如下:
go tool pprof -svg ./cpu.pprof
总结 以上是内存溢出为你收集整理的Golang单元测试、最大子数组、效能分析全部内容,希望文章能够帮你解决Golang单元测试、最大子数组、效能分析所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)