一个博文引起代码优化的思路
-
参考博文:一步步提升Go语言生成随机字符串的效率
-
根据自己的理解写出来的性能测试函数:
package generateString
import(
"time"
"testing"
"math/rand"
)
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
const letterBtyes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const letterIdxBits = 6
const letterIdxMask = 1 << letterIdxBits -1
const letterIdxMax = 63 /letterIdxBits
var src = rand.NewSource(time.Now().UnixNano())
func init(){
rand.Seed(time.Now().UnixNano())
}
// 常见做法
func RandStringRunes(n int) string {
b := make([]rune,n)
for i:= range b{
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
// bytes改进
func RandStringByte(n int) string{
b := make([]byte,n)
for i := range b{
b[i] = letterBtyes[rand.Intn(len(letterBtyes))]
}
return string(b)
}
// 余数改进
func RandStringByteRmndr(n int)string{
b := make([]byte,n)
for i:= range b{
b[i] = letterBtyes[rand.Int63()%int64(len(letterBtyes))]
}
return string(b)
}
// 掩码
func RandStringByteMask(n int)string{
b := make([]byte,n)
for i:=0;i<n;{
// & 按位与
if idx := int(rand.Int63()&letterIdxMask);idx < len(letterBtyes){
b[i] = letterBtyes[idx]
i++
}
}
return string(b)
}
// 掩码改进,保证公平性的利用资源
func RandStringByteMaskImpr(n int)string{
b := make([]byte,n)
for i,cache,remain := n-1,src.Int63(),letterIdxMax;i>=0;{
if remain==0{
cache,remain = src.Int63(),letterIdxMax
}
if idx := int(cache & letterIdxMask);idx < len(letterBtyes) {
b[i] = letterBtyes[idx]
i--
}
cache >>= letterIdxBits //可以移动十次
remain-- //修改十次
}
return string(b)
}
func BenchmarkRandStringRunes(b *testing.B){
for i:=0;i<b.N;i++{
RandStringRunes(5)
}
}
func BenchmarkRandStringBytes(b *testing.B){
for i:=0;i<b.N;i++{
RandStringByte(5)
}
}
func BenchmarkRandStringByteRmndr(b *testing.B){
for i:=0;i<b.N;i++{
RandStringByteRmndr(5)
}
}
func BenchmarkRandStringByteMask(b *testing.B){
for i:=0;i<b.N;i++{
RandStringByteMask(5)
}
}
// 这部分缩短的时间太多了吧
func BenchmarkRandStringByteMaskTmpr(b *testing.B){
for i:=0;i<b.N;i++{
RandStringByteMaskImpr(5)
}
}
- 输出结果
goos: windows
goarch: amd64
BenchmarkRandStringRunes-8 5756960 219 ns/op 40 B/op 2 allocs/op
BenchmarkRandStringBytes-8 8533357 146 ns/op 10 B/op 2 allocs/op
BenchmarkRandStringByteRmndr-8 9865086 125 ns/op 10 B/op 2 allocs/op
BenchmarkRandStringByteMask-8 8979186 141 ns/op 10 B/op 2 allocs/op
BenchmarkRandStringByteMaskTmpr-8 20043025 61.9 ns/op 10 B/op 2 allocs/op
PASS
ok command-line-arguments 7.266s
- 优化代码的思路
- 要拥有的工具:学会使用go test中性能测试
- 通过使用性能测试工具,找到耗时的地方
- 内存资源尽可能多的利用