forked from emscripten-core/emscripten
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind_bigfuncs.py
119 lines (100 loc) · 3.85 KB
/
find_bigfuncs.py
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
116
117
118
119
# Copyright 2013 The Emscripten Authors. All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License. Both these licenses can be
# found in the LICENSE file.
"""Tool to find or compare big functions in a js or ll file
"""
import sys
def humanbytes(nbytes):
if nbytes > 9 * 1024 * 1024:
return '{}MB'.format(nbytes / 1024 / 1024)
elif nbytes > 9 * 1024:
return '{}KB'.format(nbytes / 1024)
else:
return '{}B'.format(nbytes)
def processfile(filename):
start = None
curr = None
nbytes = None
data = {}
for i, line in enumerate(open(filename)):
if line.startswith(('function ', 'define ', ' (func ')) and '}' not in line:
start = i
curr = line
nbytes = len(line)
elif line.startswith(('}', ' )')) and curr:
nlines = i - start
data[curr] = (nlines, nbytes + 1)
curr = None
start = None
elif curr:
nbytes += len(line)
return data
def common_compare(data1, data2):
fns1 = set(data1.keys())
fns2 = set(data2.keys())
commonfns = fns1.intersection(fns2)
commonlinediff = 0
commonbytediff = 0
for fn in commonfns:
d1 = data1[fn]
d2 = data2[fn]
commonlinediff += d2[0] - d1[0]
commonbytediff += d2[1] - d1[1]
linesword = 'more' if commonlinediff >= 0 else 'less'
bytesword = 'more' if commonbytediff >= 0 else 'less'
print('file 2 has {} lines {} than file 1 in {} common functions'.format(abs(commonlinediff), linesword, len(commonfns)))
print('file 2 has {} {} than file 1 in {} common functions'.format(humanbytes(abs(commonbytediff)), bytesword, len(commonfns)))
def uniq_compare(data1, data2):
fns1 = set(data1.keys())
fns2 = set(data2.keys())
uniqfns1 = fns1 - fns2
uniqfns2 = fns2 - fns1
uniqlines1 = 0
uniqbytes1 = 0
uniqlines2 = 0
uniqbytes2 = 0
for fn in uniqfns1:
d = data1[fn]
uniqlines1 += d[0]
uniqbytes1 += d[1]
for fn in uniqfns2:
d = data2[fn]
uniqlines2 += d[0]
uniqbytes2 += d[1]
uniqcountdiff = len(uniqfns2) - len(uniqfns1)
assert len(fns2) - len(fns1) == uniqcountdiff
uniqlinediff = uniqlines2 - uniqlines1
uniqbytediff = uniqbytes2 - uniqbytes1
countword = 'more' if uniqcountdiff >= 0 else 'less'
linesword = 'more' if uniqlinediff >= 0 else 'less'
bytesword = 'more' if uniqbytediff >= 0 else 'less'
print('file 2 has {} functions {} than file 1 overall (unique: {} vs {})'.format(abs(uniqcountdiff), countword, len(uniqfns2), len(uniqfns1)))
print('file 2 has {} lines {} than file 1 overall in unique functions'.format(abs(uniqlinediff), linesword))
print('file 2 has {} {} than file 1 overall in unique functions'.format(humanbytes(abs(uniqbytediff)), bytesword))
def list_bigfuncs(data):
data = list(data.items())
data.sort(key=lambda f_d: f_d[1][0])
print(''.join(['%6d lines (%6s) : %s' % (d[0], humanbytes(d[1]), f) for f, d in data]))
def main():
if len(sys.argv) < 2 or len(sys.argv) > 3 or sys.argv[1] == '--help':
print('Usage:')
print(' {} file1 - list functions in a file in ascending order of size'.format(sys.argv[0]))
print(' {} file1 file2 - compare functions across two files'.format(sys.argv[0]))
return 1
if len(sys.argv) == 2:
filename = sys.argv[1]
data = processfile(filename)
list_bigfuncs(data)
return 0
if len(sys.argv) == 3:
filename1 = sys.argv[1]
data1 = processfile(filename1)
filename2 = sys.argv[2]
data2 = processfile(filename2)
uniq_compare(data1, data2)
common_compare(data1, data2)
return 0
assert False
if __name__ == '__main__':
sys.exit(main())