forked from brendangregg/FlameGraph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
difffolded.pl
executable file
·115 lines (106 loc) · 3.55 KB
/
difffolded.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/perl -w
#
# difffolded.pl diff two folded stack files. Use this for generating
# flame graph differentials.
#
# USAGE: ./difffolded.pl [-hns] folded1 folded2 | ./flamegraph.pl > diff2.svg
#
# Options are described in the usage message (-h).
#
# The flamegraph will be colored based on higher samples (red) and smaller
# samples (blue). The frame widths will be based on the 2nd folded file.
# This might be confusing if stack frames disappear entirely; it will make
# the most sense to ALSO create a differential based on the 1st file widths,
# while switching the hues; eg:
#
# ./difffolded.pl folded2 folded1 | ./flamegraph.pl --negate > diff1.svg
#
# Here's what they mean when comparing a before and after profile:
#
# diff1.svg: widths show the before profile, colored by what WILL happen
# diff2.svg: widths show the after profile, colored by what DID happen
#
# INPUT: See stackcollapse* programs.
#
# OUTPUT: The full list of stacks, with two columns, one from each file.
# If a stack wasn't present in a file, the column value is zero.
#
# folded_stack_trace count_from_folded1 count_from_folded2
#
# eg:
#
# funca;funcb;funcc 31 33
# ...
#
# COPYRIGHT: Copyright (c) 2014 Brendan Gregg.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# (http://www.gnu.org/copyleft/gpl.html)
#
# 28-Oct-2014 Brendan Gregg Created this.
use strict;
use Getopt::Std;
# defaults
my $normalize = 0; # make sample counts equal
my $striphex = 0; # strip hex numbers
sub usage {
print STDERR <<USAGE_END;
USAGE: $0 [-hns] folded1 folded2 | flamegraph.pl > diff2.svg
-h # help message
-n # normalize sample counts
-s # strip hex numbers (addresses)
See stackcollapse scripts for generating folded files.
Also consider flipping the files and hues to highlight reduced paths:
$0 folded2 folded1 | ./flamegraph.pl --negate > diff1.svg
USAGE_END
exit 2;
}
usage() if @ARGV < 2;
our($opt_h, $opt_n, $opt_s);
getopts('ns') or usage();
usage() if $opt_h;
$normalize = 1 if defined $opt_n;
$striphex = 1 if defined $opt_s;
my ($total1, $total2) = (0, 0);
my %Folded;
my $file1 = $ARGV[0];
my $file2 = $ARGV[1];
open FILE, $file1 or die "ERROR: Can't read $file1\n";
while (<FILE>) {
chomp;
my ($stack, $count) = (/^(.*)\s+?(\d+(?:\.\d*)?)$/);
$stack =~ s/0x[0-9a-fA-F]+/0x.../g if $striphex;
$Folded{$stack}{1} += $count;
$total1 += $count;
}
close FILE;
open FILE, $file2 or die "ERROR: Can't read $file2\n";
while (<FILE>) {
chomp;
my ($stack, $count) = (/^(.*)\s+?(\d+(?:\.\d*)?)$/);
$stack =~ s/0x[0-9a-fA-F]+/0x.../g if $striphex;
$Folded{$stack}{2} += $count;
$total2 += $count;
}
close FILE;
foreach my $stack (keys %Folded) {
$Folded{$stack}{1} = 0 unless defined $Folded{$stack}{1};
$Folded{$stack}{2} = 0 unless defined $Folded{$stack}{2};
if ($normalize && $total1 != $total2) {
$Folded{$stack}{1} = int($Folded{$stack}{1} * $total2 / $total1);
}
print "$stack $Folded{$stack}{1} $Folded{$stack}{2}\n";
}