Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Профилирование и оптимизация программ на Go
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Alexey Palazhchenko
April 14, 2017
Programming
490
3
Share
Профилирование и оптимизация программ на Go
Доклад на конференции Стачка 2017
Alexey Palazhchenko
April 14, 2017
More Decks by Alexey Palazhchenko
See All by Alexey Palazhchenko
Using PostgreSQL's Background Worker Processes For Fun and Profit
aleksi
0
170
Песнь Хорьков и Гоферов
aleksi
0
380
Fuzzy generics
aleksi
0
190
On Ferrets and Gophers
aleksi
0
270
How to Go Wrong with Concurrency
aleksi
2
790
Adding context to existing code
aleksi
1
160
Зачем и как написать свой database/sql драйвер
aleksi
1
200
Cooking gRPC
aleksi
1
910
Profiling and Optimizing Go Programs
aleksi
1
1.8k
Other Decks in Programming
See All in Programming
「速くなった気がする」をデータで疑う
senleaf24
0
130
一度始めたらやめられない開発効率向上術 / Findy あなたのdotfilesを教えて!
k0kubun
3
2.7k
ロボットのための工場に灯りは要らない
watany
12
3.3k
L’IA au service des devs : Anatomie d'un assistant de Code Review
toham
0
190
2026-03-27 #terminalnight 変数展開とコマンド展開でターミナル作業をスマートにする方法
masasuzu
0
280
Smarter Angular mit Transformers.js & Prompt API
christianliebel
PRO
1
110
Strategy for Finding a Problem for OSS: With Real Examples
kibitan
0
130
PHPのバージョンアップ時にも役立ったAST(2026年版)
matsuo_atsushi
0
280
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
3
440
forteeの改修から振り返るPHPerKaigi 2026
muno92
PRO
3
120
Symfonyの特性(設計思想)を手軽に活かす特性(trait)
ickx
0
120
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
110
Featured
See All Featured
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.9k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
90
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
190
The World Runs on Bad Software
bkeepers
PRO
72
12k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
470
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
500
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
180
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
240
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.8k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.7k
Transcript
Профилирование и оптимизация программ на Go Алексей Палажченко 14 апреля
2017, Стачка
Профилирование и оптимизация программ на Go Алексей Палажченко 14 апреля
2017, Стачка
None
None
None
None
None
None
type Cache interface { Get(id string) interface{} Set(id string, value
interface{}) Len() int }
func (s *Slice) Get(id string) interface{} { for _, it
:= range s.items { if it.id == id { return it.value } } return nil }
func (s *Slice) Set(id string, value i{}) { for i,
it := range s.items { if it.id == id { s.items[i].value = value return } } s.items = append(s.items, item{id, value}) }
func (s *Slice) Set(id string, value i{}) { for i,
it := range s.items { if it.id == id { s.items[i].value = value return } } s.items = append(s.items, item{id, value}) }
b.ResetTimer() for i := 0; i < b.N; i++ {
for _, id := range ids { Sink = c.Get(id) } }
100 200 300 400 0 1 2 3 4 5
6 7 8 9 10 Slice Map
100 200 300 400 0 1 2 3 4 5
6 7 8 9 10 Slice Map Fancy algorithms are slow when n is small, and n is usually small. - Rob Pike
Sink func popcnt(x uint64) int { var res uint64 for
; x > 0; x >>= 1 { res += x & 1 } return int(res) }
Sink const m1 = 0x5555555555555555 const m2 = 0x3333333333333333 const
m4 = 0x0f0f0f0f0f0f0f0f const h01 = 0x0101010101010101 func popcnt2(x uint64) int { x -= (x >> 1) & m1 x = (x & m2) + ((x >> 2) & m2) x = (x + (x >> 4)) & m4 return int((x * h01) >> 56) }
Sink func BenchmarkPopcnt(b *testing.B) { for i := 0; i
< b.N; i++ { popcnt(uint64(i)) } } func BenchmarkPopcnt2(b *testing.B) { for i := 0; i < b.N; i++ { popcnt2(uint64(i)) } }
Sink go test -v -bench=. BenchmarkPopcnt-4 100000000 15.5 ns/op BenchmarkPopcnt2-4
2000000000 0.34 ns/op
Sink go test -v -bench=. BenchmarkPopcnt-4 100000000 15.5 ns/op BenchmarkPopcnt2-4
2000000000 0.34 ns/op
Sink • go doc compile • go test -bench=. -gcflags
"-S"
Sink popcnt_test.go:14 MOVQ "".b+8(FP), AX popcnt_test.go:14 MOVQ $0, CX popcnt_test.go:14
MOVQ 200(AX), DX popcnt_test.go:14 CMPQ CX, DX popcnt_test.go:14 JGE $0, 34 popcnt_test.go:14 INCQ CX popcnt_test.go:14 MOVQ 200(AX), DX popcnt_test.go:14 CMPQ CX, DX popcnt_test.go:14 JLT $0, 19 popcnt_test.go:17 RET
Sink func BenchmarkPopcnt(b *testing.B) { for i := 0; i
< b.N; i++ { Sink = popcnt(uint64(i)) } } func BenchmarkPopcnt2(b *testing.B) { for i := 0; i < b.N; i++ { Sink = popcnt2(uint64(i)) } }
Sink go test -v -bench=. BenchmarkPopcnt-4 50000000 39.3 ns/op BenchmarkPopcnt2-4
50000000 26.8 ns/op
Sink env GOSSAFUNC=BenchmarkPopcnt2 go test -bench=.
Benchmarks • Не в виртуальной машине • Не трогать во
время работы • Выключить автоматическое управление питанием • rsc.io/benchstat
pprof • runtime/pprof • net/http/pprof • go test • Не
больше одного за раз!
pprof: CPU • setitimer(2), ITIMER_PROF, SIGPROF • До 500 Гц
(100 по умолчанию) • SetCPUProfileRate(hz) • go test -bench=XXX -cpuprofile=XXX.pprof • go tool pprof -svg -output=XXX.svg cache.test XXX.pprof
None
None
pprof: mem/block/mutex • pprof.MemProfileRate = bytes • pprof.SetBlockProfileRate(ns) • pprof.SetMutexProfileFraction(rate)
type Map struct { m sync.Mutex items map[string]interface{} } func
(m *Map) Get(id string) interface{} { m.m.Lock() defer m.m.Unlock() return m.items[id] }
pprof: block • go test -v -bench=XXX -blockprofile=XXX.pprof • go
tool pprof -svg -lines -output=XXX.svg ccache.test XXX.pprof
None
type Map struct { m sync.RWMutex items map[string]interface{} } func
(m *Map) Get(id string) interface{} { m.m.RLock() v := m.items[id] m.m.RUnlock() return v }
pprof: свои профили • Когда нужны stack traces • Интеграция
с go tool pprof • Пример: открытие и закрытие файлов • pprof.NewProfile, pprof.Lookup • Profile.Add, Remove
Execution tracer • Запуск, остановка, переключение горутин • Блокировки на
каналах, select • Блокировки на mutex’ах • Блокировки на сети, syscall’ах
Execution tracer • Все события с полным контекстом • Большие
файлы (со всеми символами) • Замедление ~25% • pprof CPU для throughput, tracer для latency
Execution tracer • import _ "net/http/pprof" • http://127.0.0.1:8080/debug/pprof • redis-benchmark
-r 100000 -e -l -t set,get • go tool trace trace.out
Execution tracer • go tool trace -pprof=TYPE trace.out > TYPE.pprof
• net • sync • syscall • sched
Linux • perf (perf_events) • SystemTap • BPF (eBPF)
Переменные окружения • GOGC (100, off) • GODEBUG • gctrace=1
• allocfreetrace=1 • schedtrace=1000
Оптимизации • struct{} • m[string(b)] • for i, c :=
range []byte(s) • for i := range s { a[i] = <zero value> }
Оптимизации type Key [64]byte type Value struct { Name [32]byte
Balance uint64 Timestamp int64 } m := make(map[Key]Value, 1e8)
• golang-ru @ Google Groups • 4gophers.ru/slack • golangshow.com •
github.com/AlekSi/ stachka-2017