Skip to content

Commit 4ec8b28

Browse files
authored
Bloat stats (#6132)
1 parent 558e241 commit 4ec8b28

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Usage:
2+
3+
$cd ~/github/ydb/ydb/library/yql/tools/yqlrun
4+
$ ~/github/ydb/ydb/library/yql/scripts/bloat/bloat.sh
5+
6+
it generates two files in current directory:
7+
8+
$PGM.by_size.txt
9+
$PGM.by_count.txt
10+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
set -eux
3+
BASEDIR="$(dirname $(readlink -f $0))"
4+
PGM=$(awk '/PROGRAM\((.*)\)/{ print substr($1, 9, length($1) - 9) }' ya.make)
5+
YA=$BASEDIR/../../../../../ya
6+
$YA make --build relwithdebinfo -DDUMP_LINKER_MAP
7+
du -s -BM $(readlink $PGM)
8+
$YA tool bloat --input ./$PGM --linker-map ./$PGM.map.lld --save-json ./$PGM.json
9+
$BASEDIR/parse_bloat.py ./$PGM
10+
11+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python3
2+
import sys
3+
import json
4+
import os
5+
6+
class Walker:
7+
def __init__(self):
8+
self.stats = {}
9+
10+
def process(self, node):
11+
if node["type"] == "file":
12+
self.current_file = node["name"]
13+
if "children" in node:
14+
for child in node["children"]:
15+
self.process(child)
16+
return
17+
if node["type"] != "fn":
18+
return
19+
name = node["name"]
20+
inside_template = 0
21+
final_name = ""
22+
for c in name:
23+
if c == '<':
24+
inside_template += 1
25+
if inside_template == 1:
26+
final_name += c
27+
elif c == '>':
28+
inside_template -= 1
29+
if inside_template == 0:
30+
final_name += c
31+
else:
32+
if inside_template:
33+
continue
34+
final_name += c
35+
if final_name not in self.stats:
36+
self.stats[final_name] = [0,0,set()]
37+
self.stats[final_name][0] += node["size"]
38+
self.stats[final_name][1] += 1
39+
self.stats[final_name][2].add(self.current_file)
40+
41+
def print_stat(f, p):
42+
print("{} size={} count={}".format(p[0],p[1][0],p[1][1]), file=f)
43+
for s in sorted(p[1][2]):
44+
print(" " + s, file=f)
45+
46+
def main():
47+
pgm = sys.argv[1]
48+
with open(pgm + ".json") as f:
49+
data = json.load(f)
50+
walker = Walker()
51+
walker.process(data["tree"])
52+
with open(pgm + ".by_size.txt","w") as f:
53+
for p in sorted(walker.stats.items(), key=lambda p: p[1][0], reverse=True):
54+
print_stat(f, p)
55+
with open(pgm + ".by_count.txt","w") as f:
56+
for p in sorted(walker.stats.items(), key=lambda p: p[1][1], reverse=True):
57+
print_stat(f, p)
58+
return 0
59+
60+
if __name__ == "__main__":
61+
sys.exit(main())
62+

0 commit comments

Comments
 (0)