You've already forked go-profiler-notes
mirror of
https://github.com/DataDog/go-profiler-notes.git
synced 2025-07-15 23:54:16 +02:00
more examples
This commit is contained in:
55
examples/block-vs-mutex/main.go
Normal file
55
examples/block-vs-mutex/main.go
Normal file
@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
runtime.SetBlockProfileRate(1)
|
||||
runtime.SetMutexProfileFraction(1)
|
||||
|
||||
aquired := make(chan struct{})
|
||||
var m sync.Mutex
|
||||
m.Lock()
|
||||
go func() {
|
||||
<-aquired
|
||||
m.Lock()
|
||||
aquired <- struct{}{}
|
||||
}()
|
||||
aquired <- struct{}{}
|
||||
time.Sleep(time.Nanosecond)
|
||||
m.Unlock()
|
||||
<-aquired
|
||||
|
||||
if err := writeProfile("block"); err != nil {
|
||||
return err
|
||||
} else if err := writeProfile("mutex"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeProfile(name string) error {
|
||||
f, err := os.Create(name + ".pb.gz")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := pprof.Lookup(name).WriteTo(f, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
BIN
examples/block/main
Executable file
BIN
examples/block/main
Executable file
Binary file not shown.
76
examples/block/main.go
Normal file
76
examples/block/main.go
Normal file
@ -0,0 +1,76 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var foo []string
|
||||
|
||||
func main() {
|
||||
demonstrateSleep()
|
||||
|
||||
f, err := os.Create("block.pb.gz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := pprof.Lookup("block").WriteTo(f, 0); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func demonstrateSleep() {
|
||||
runtime.SetBlockProfileRate(1)
|
||||
<-time.After(time.Millisecond)
|
||||
}
|
||||
|
||||
func demonstrateSelect() {
|
||||
runtime.SetBlockProfileRate(1)
|
||||
|
||||
ch1 := make(chan struct{}, 0)
|
||||
ch2 := make(chan struct{}, 1)
|
||||
ch3 := make(chan struct{}, 0)
|
||||
|
||||
go func() {
|
||||
ch2 <- struct{}{}
|
||||
}()
|
||||
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
|
||||
select {
|
||||
case <-ch1:
|
||||
case <-ch2:
|
||||
case <-ch3:
|
||||
}
|
||||
}
|
||||
|
||||
func demonstrateSampling() {
|
||||
runtime.SetBlockProfileRate(int(40 * time.Microsecond.Nanoseconds()))
|
||||
for i := 0; i < 10000; i++ {
|
||||
blockMutex(10 * time.Microsecond)
|
||||
}
|
||||
}
|
||||
|
||||
func blockMutex(d time.Duration) {
|
||||
m := &sync.Mutex{}
|
||||
m.Lock()
|
||||
go func() {
|
||||
spinSleep(d)
|
||||
m.Unlock()
|
||||
}()
|
||||
m.Lock()
|
||||
}
|
||||
|
||||
// spinSleep is a more accurate version of time.Sleep() for short sleep
|
||||
// durations. Accuracy seems to be ~35ns.
|
||||
func spinSleep(d time.Duration) {
|
||||
start := time.Now()
|
||||
n := 0
|
||||
for time.Since(start) < d {
|
||||
n++
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user