forked from matstc/shell-profiler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprofile
executable file
·75 lines (56 loc) · 2.23 KB
/
profile
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
#!/usr/bin/env python
import sys
import subprocess
import time
def trace():
popen = subprocess.Popen(["/bin/bash"], bufsize=1, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
code = open(arguments[1],'r').read()
popen.stdin.write("set %s;" % ' '.join(arguments[1:]))
popen.stdin.write("export PS4='>:`date +%s.%N`:$0:line $LINENO:'; set -x;")
popen.stdin.write(code)
popen.stdin.write("echo --- END OF PROFILING ---")
popen.stdin.close()
print "Done executing."
return popen.stderr.readlines()
def collect_timings(tokens, index):
if index == len(tokenized_trace) -1:
return [0] + tokens
if DEBUG:
print "tokenized trace is: %s" % tokenized_trace
print "tokens are %s" % tokens
timing = float(tokenized_trace[index+1][1].replace(".N", "")) - float(tokens[1].replace(".N", ""))
return [timing] + tokens
def consolidate_timings_by_line(timings):
profiling_info_by_line = {}
for tokens in timings:
key = "%s:%s" % (tokens[3], tokens[4])
if key not in profiling_info_by_line:
profiling_info_by_line[key] = tokens
else:
profiling_info_by_line[key][0] += tokens[0]
return profiling_info_by_line.values()
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
def format_token(token):
if is_number(token):
return '%.9f' % token
else:
return token
def output(all_timings):
[sys.stderr.write("\t".join([format_token(t) for t in (timings[:2] + timings[3:])])) for timings in all_timings]
if __name__ == '__main__':
DEBUG = "--debug" in sys.argv
arguments = filter(lambda x: x != "--debug", sys.argv)
if len(arguments) < 2:
print "Usage: call this script with the path to another script to profile."
print "e.g.: %s /some/path/script.sh param1 param2" % arguments[0]
exit(1)
tmp_tokens = [line.split(":") for line in trace()]
tokenized_trace = [tmp[:4] + [':'.join(tmp[4:])] for tmp in tmp_tokens] #to recombine code lines that actually contain semi-colons
profiling_with_timings = map(collect_timings, tokenized_trace, range(len(tokenized_trace)))
consolidated_timings_by_line = consolidate_timings_by_line(profiling_with_timings)
output(sorted(consolidated_timings_by_line, key=lambda tokens: tokens[0], reverse=True))