Go语言性能优化实战

过早优化是万恶之源,这里都是黑魔法,不是性能瓶颈慎用

  • 根据pprof数据优化
  • 尽量避免GC,所以要避免创建过多的对象,也可以通过设置 GOGC 环境变量来增加触发GC的阈值,缺点是费内存。
  • 尽量的复用已经创建的对象,其中就包括如果可以的话,预先创建好对象。参考: https://golang.org/pkg/sync/#Pool
  • 避免锁,可以考虑 CAS。https://golang.org/pkg/sync/atomic/
  • 如果可以的话,用struct代替map。一个简单的例子就可以说明:
package main

type structDemoStruct struct {
	First int
}

var (
	mapDemo    = make(map[int]int, 1)
	structDemo = structDemoStruct{}
)

func mapIncr() {
	mapDemo[1]++
}

func structIncr() {
	structDemo.First++
}
package main

import (
	"testing"
)

func BenchmarkMap(b *testing.B) {
	for i := 0; i < b.N; i++ {
		mapIncr()
	}
}

func BenchmarkStruct(b *testing.B) {
	for i := 0; i < b.N; i++ {
		structIncr()
	}
}

测试结果:

$ go test -bench .
goos: linux
goarch: amd64
BenchmarkMap-4      	100000000	        20.5 ns/op
BenchmarkStruct-4   	1000000000	         2.02 ns/op
PASS
ok  	_/home/jiajun/tests	4.299s
  • defer 虽然好用,但是也会带来性能损伤。如果是高并发的服务,可能要注意一下
  • time.Now 比你想象中的慢,如果时间精确度不高,可以自己实现一个粗略的时钟
  • []byte和string转换比你想象中的慢,而且不能愉快的重复利用
  • 减少锁的使用,缩小临界区
  • 如果是CPU Bound的话,可以考虑设置 GOGC 来用内存换CPU时间

微信公众号
关注公众号,获得及时更新

更多文章
  • 密码技术简明教程(一):对称加密和非对称加密
  • Kubernetes 笔记
  • go mod 和 logrus 路径大小写的问题
  • Flask自动加载Blueprint
  • 在KVM里安装Minikube
  • 搞定面试中的系统设计题
  • Crontab + Sendmail实现定时任务并且通知
  • Nginx设置Referer来防止盗图
  • Graphviz dot简明教程
  • jQuery简明教程
  • Python RQ(Redis Queue)添加gevent支持
  • 读《超级运营术》- 如何做社区?
  • 技术人,光有技术是不行的
  • 搭建aria2服务器
  • 使用shairport-sync搭建airplay音频服务器