Stackprof: weight on-cpu samples by period rather than timestamp delta (#425)

This attempts to improve the quality of the on-CPU profiles stackprof provides. Rather than weighing samples by their timestamp deltas, which, in our opinion, are only valid in wall-clock mode, this weighs callchains by:


```
S = number of samples
P = sample period in nanoseconds

W = S * P
```

The difference after this change is quite substantial, specially in profiles that previously were showing up with heavy IO frames:  

* Total profile weight is almost down by 90%, which actually makes sense for an on-CPU profile if the app is relatively idle
* Certain callchains that blocked in syscalls / IO are now much lower weight. This was what I was expecting to find.
Here is an example of the latter point.

In delta mode, we see an io select taking a long time, it is a significant portion of the profile:

<img width="1100" alt="236936508-709bee01-d616-4246-ba74-ab004331dcd3" src="https://github.com/dalehamel/speedscope/assets/4398256/39140f1e-50a9-4f33-8a61-ec98b6273fd4">

But in period scaling mode, it is only a couple of sample periods ultimately:

<img width="206" alt="236936693-9d44304e-a1c2-4906-b3c8-50e19e6f9f27" src="https://github.com/dalehamel/speedscope/assets/4398256/7d19077f-ef25-4d79-980b-cfa1775d928d">
This commit is contained in:
Manuel Correa
2023-06-17 20:50:19 -07:00
committed by GitHub
parent e9133be353
commit 741fdeb427
5 changed files with 501 additions and 21 deletions
File diff suppressed because one or more lines are too long
+8 -2
View File
@@ -5,6 +5,7 @@ def a
for i in 0..100 do
b
c
e
end
end
@@ -28,8 +29,13 @@ def d
prod
end
profile = StackProf.run(mode: :wall, raw: true) do
def e
sleep 0.05
end
mode = (ARGV[0] || :wall).to_sym
profile = StackProf.run(mode: mode, raw: true) do
a
end
puts JSON.generate(profile)
puts JSON.generate(profile)
@@ -1,5 +1,453 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`importCpuProfileWithProperWeights importFromStackprof cpu mode snapshot 1`] = `
Object {
"frames": Array [
Frame {
"col": undefined,
"file": "sample/programs/ruby/simple.rb",
"key": 5352342240,
"line": undefined,
"name": "<main>",
"selfWeight": 0,
"totalWeight": 410000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 4530376200,
"line": undefined,
"name": "<main>",
"selfWeight": 0,
"totalWeight": 410000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 4530486680,
"line": 37,
"name": "block in <main>",
"selfWeight": 0,
"totalWeight": 410000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 5335911080,
"line": 4,
"name": "Object#a",
"selfWeight": 0,
"totalWeight": 410000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 5335911040,
"line": 12,
"name": "Object#b",
"selfWeight": 0,
"totalWeight": 154000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 5335909920,
"line": 24,
"name": "Object#d",
"selfWeight": 331000,
"totalWeight": 331000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 5335910560,
"line": 18,
"name": "Object#c",
"selfWeight": 0,
"totalWeight": 177000,
},
Frame {
"col": undefined,
"file": "/Users/mcorrea/src/github.com/dalehamel/speedscope/sample/programs/ruby/simple.rb",
"key": 5335909880,
"line": 32,
"name": "Object#e",
"selfWeight": 79000,
"totalWeight": 79000,
},
Frame {
"col": undefined,
"file": "",
"key": 1,
"line": undefined,
"name": "(garbage collection)",
"selfWeight": 0,
"totalWeight": 79000,
},
Frame {
"col": undefined,
"file": "",
"key": 5,
"line": undefined,
"name": "(sweeping)",
"selfWeight": 71000,
"totalWeight": 71000,
},
Frame {
"col": undefined,
"file": "",
"key": 3,
"line": undefined,
"name": "(marking)",
"selfWeight": 8000,
"totalWeight": 8000,
},
],
"name": "simple-cpu-stackprof.json",
"stacks": Array [
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 5.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(marking) 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"(garbage collection);(sweeping) 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 5.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 5.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 4.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(marking) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 5.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 1.00ms",
"(garbage collection);(sweeping) 2.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#e 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 4.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#b;Object#b;Object#d;Object#d 2.00ms",
"(garbage collection);(sweeping) 1.00ms",
"<main>;<main>;block in <main>;Object#a;Object#a;Object#c;Object#c;Object#d;Object#d 3.00ms",
],
}
`;
exports[`importCpuProfileWithProperWeights importFromStackprof cpu mode snapshot: indexToView 1`] = `0`;
exports[`importCpuProfileWithProperWeights importFromStackprof cpu mode snapshot: profileGroup.name 1`] = `"simple-cpu-stackprof.json"`;
exports[`importFromStackprof 1`] = `
Object {
"frames": Array [
+25
View File
@@ -1,3 +1,5 @@
import { readFileSync } from 'fs';
import { importProfileGroupFromText } from '.'
import {checkProfileSnapshot} from '../lib/test-utils'
test('importFromStackprof', async () => {
@@ -11,3 +13,26 @@ test('importFromStackprof object mode', async () => {
test('importFromStackprof when a profile has a frame with no name', async () => {
await checkProfileSnapshot('./sample/profiles/stackprof/stackprof-last-frame-no-name.json')
})
describe('importCpuProfileWithProperWeights', () => {
test('importFromStackprof cpu mode snapshot', async () => {
await checkProfileSnapshot('./sample/profiles/stackprof/simple-cpu-stackprof.json')
})
test('uses samples count for weight when importing cpu profile', async () => {
const profileFile = readFileSync('./sample/profiles/stackprof/simple-cpu-stackprof.json')
const profileGroup = await importProfileGroupFromText('simple-cpu-stackprof.json', profileFile.toString())
expect(profileGroup).not.toBeNull()
if (profileGroup) {
const profile = profileGroup.profiles[profileGroup.indexToView]
expect(profile).not.toBeNull()
if (profile) {
expect(profile.getWeightUnit()).toBe('microseconds')
expect(profile.getTotalWeight()).toBe(489000)
}
}
})
})
+19 -19
View File
@@ -1,7 +1,7 @@
// https://github.com/tmm1/stackprof
import {Profile, FrameInfo, StackListProfileBuilder} from '../lib/profile'
import {TimeFormatter} from '../lib/value-formatters'
import {RawValueFormatter, TimeFormatter} from '../lib/value-formatters'
interface StackprofFrame {
name?: string
@@ -15,14 +15,13 @@ export interface StackprofProfile {
raw: number[]
raw_timestamp_deltas: number[]
samples: number
interval: number
}
export function importFromStackprof(stackprofProfile: StackprofProfile): Profile {
const {frames, mode, raw, raw_timestamp_deltas, samples} = stackprofProfile
const objectMode = mode == 'object'
const size = objectMode ? samples : stackprofProfile.raw_timestamp_deltas.reduce((a, b) => a + b, 0)
const profile = new StackListProfileBuilder(size)
const {frames, mode, raw, raw_timestamp_deltas, interval} = stackprofProfile
const profile = new StackListProfileBuilder()
profile.setValueFormatter(new TimeFormatter('microseconds')) // default to time format unless we're in object mode
let sampleIndex = 0
@@ -50,23 +49,24 @@ export function importFromStackprof(stackprofProfile: StackprofProfile): Profile
}
const nSamples = raw[i++]
if (objectMode) {
profile.appendSampleWithWeight(stack, nSamples)
} else {
let sampleDuration = 0
for (let j = 0; j < nSamples; j++) {
sampleDuration += raw_timestamp_deltas[sampleIndex++]
}
profile.appendSampleWithWeight(stack, sampleDuration)
switch (mode) {
case 'object':
profile.appendSampleWithWeight(stack, nSamples)
profile.setValueFormatter(new RawValueFormatter())
break
case 'cpu':
profile.appendSampleWithWeight(stack, nSamples * interval)
break
default:
let sampleDuration = 0
for (let j = 0; j < nSamples; j++) {
sampleDuration += raw_timestamp_deltas[sampleIndex++]
}
profile.appendSampleWithWeight(stack, sampleDuration)
}
prevStack = stack
}
if (!objectMode) {
profile.setValueFormatter(new TimeFormatter('microseconds'))
}
return profile.build()
}