package main
/**
无重复字符的最长字串;支持中文
*/
func lengthOfNonRepratingSubStr(s string) int {
lastOccurred := make(map[rune]int)
start := 0
maxLen := 0
for i, ch := range []rune(s) {
if lastIndex, ok := lastOccurred[ch]; ok && lastIndex >= start {
start = lastIndex + 1
}
if i-start+1 > maxLen {
maxLen = i - start + 1
}
lastOccurred[ch] = i
}
return maxLen
}
性能测试
func BenchmarkSubStr(b *testing.B) {
param := "黑化肥挥发发灰会花飞灰化肥挥发发黑会飞花"
for i := 0; i < 13; i++ {
param = param + param
}
b.Logf("len(param) = %d",len(param))
for i := 0; i < b.N; i++ {
val := lengthOfNonRepratingSubStr(param)
ans := 8
if val != ans {
b.Errorf("lengtyum install graphvizhOfNonRepratingSubStr(%s); 期望值:%d; 实际值: %d", param, ans, val)
}
}
}
没有进行调优时,进行性能测试12920060 ns/op;不算特别慢;但是还可以更快!
Graphviz介绍使用Graphviz和pprof命令分析代码现在的问题;然后有针对性的去优化代码
Graphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局.
Graphviz安装 Graphviz本身是一个绘图工具软件,下载点击地址.如果你是linux,可以用api-get或者yum的方法安装.如果是windows,就在官网下载msi文件安装;无论是linux还是windows,装完后都要设置环境变量.
go test -bench .
go test -bench . -cpuprofile cpu.out
go tool pprof cpu.out
web
优化思路
我们通过命令+Graphviz生成出一张图;这张图的方框有大有小;线有粗有细,方框越大消耗的时间越长,线越粗消耗的时间越长通过对图片的分析
mapaccess2_fast32 0.38s (18.18%) of 0.62s (29.67%)mapassign_fast32 0.39s (18.66%) of 0.57s (27.27%)stringtoslicerune 0.20s (9.57%) of 0.49s (23.44%)
主要是map和把参数转成[]rune消耗比较大;但是我们有utf8字符串传进来,解码是必不可少的,就只能在map上进行优化
优化代码
使用数组代替map;用空间换时间.map里面每个rune塞进去,它要算哈希;要判重;要分配空间;这一系列 *** 作都太慢了;我们使用数组一开始就把空间分配好;使用空间来换时间
func lengthOfNonRepratingSubStr(s string) int {
lastOccurred := make([]int, 0xffff)
for i := range lastOccurred {
lastOccurred[i] = -1
}
start := 0
maxLen := 0
for i, ch := range []rune(s) {
if lastIndex := lastOccurred[ch]; lastIndex != -1 && lastIndex >= start {
start = lastIndex + 1
}
if i-start+1 > maxLen {
maxLen = i - start + 1
}
lastOccurred[ch] = i
}
return maxLen
}
初步优化,进行性能测试4562497 ns/op;性能提高的非常明显,肉眼可见
再次进行分析
通过对图片进行分析
我们把创建数组的动作提到函数外面,把创建数组的动作减少到一次
var lastOccurred = make([]int, 0xffff)
func lengthOfNonRepratingSubStr(s string) int {
for i := range lastOccurred {
lastOccurred[i] = -1
}
start := 0
maxLen := 0
for i, ch := range []rune(s) {
if lastIndex := lastOccurred[ch]; lastIndex != -1 && lastIndex >= start {
start = lastIndex + 1
}
if i-start+1 > maxLen {
maxLen = i - start + 1
}
lastOccurred[ch] = i
}
return maxLen
}
优化后,进行性能测试4140482 ns/op;相比上次性能测试的结果,这次更快了!
现在对图片进行分析就只剩一个必不可少的解码动作比较耗时,其他的都已经完成了优化!
总之,调优不是一蹴而就的,需要分析,推理,实践,总结,再分析,最终定位到具体的问题
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)