Skip to content

Commit 949cd9f

Browse files
authored
compute actual sample rate for profile export (#26)
In cases where due to either an excessive number of goroutines, or excessive load on the system, we are not able to sample at the given rate, we can compute the actual rate we were able to sample and use that when exporting the profile so that timing information in the profile is more accurate and sensible. With this code in place, a function which is on the stack for the entirety of a 27 second profile, will always display 27s when viewed, whereas previously it could display less time.
1 parent ececf76 commit 949cd9f

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

fgprof.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package fgprof
66
import (
77
"fmt"
88
"io"
9+
"math"
910
"runtime"
1011
"sort"
1112
"strings"
@@ -37,16 +38,19 @@ func Start(w io.Writer, format Format) func() error {
3738
const hz = 99
3839
ticker := time.NewTicker(time.Second / hz)
3940
stopCh := make(chan struct{})
40-
4141
prof := &profiler{}
4242
profile := newWallclockProfile()
4343

44+
var sampleCount int64
45+
4446
go func() {
4547
defer ticker.Stop()
4648

4749
for {
4850
select {
4951
case <-ticker.C:
52+
sampleCount++
53+
5054
stacks := prof.GoroutineProfile()
5155
profile.Add(stacks)
5256
case <-stopCh:
@@ -59,7 +63,14 @@ func Start(w io.Writer, format Format) func() error {
5963
stopCh <- struct{}{}
6064
endTime := time.Now()
6165
profile.Ignore(prof.SelfFrames()...)
62-
return profile.Export(w, format, hz, startTime, endTime)
66+
67+
// Compute actual sample rate in case, due to performance issues, we
68+
// were not actually able to sample at the given hz. Converting
69+
// everything to float avoids integers being rounded in the wrong
70+
// direction and improves the correctness of times in profiles.
71+
duration := endTime.Sub(startTime)
72+
actualHz := float64(sampleCount) / (float64(duration) / 1e9)
73+
return profile.Export(w, format, int(math.Round(actualHz)), startTime, endTime)
6374
}
6475
}
6576

0 commit comments

Comments
 (0)