#!/usr/bin/env python import sys TK_JUNK = 0 TK_ADDR = 1 TK_FILE = 2 TK_LINE = 3 TK_NAME = 4 TK_TRACE = 5 TK_ENTER = 6 TK_TIME = 7 indent = -1 def findMatchingProfileEntry(key): for func in openfuncs[::-1]: if func[0] == key: return func return None def findMatchingStackEntry(key): for func in stack[::-1]: if func[0] == key: return func return None def processProfile(line): global indent tokens = line.split(' ') key = tokens[TK_FILE] + '|' + tokens[TK_LINE] + '|' + tokens[TK_NAME] entering = tokens[TK_ENTER] if entering == '0': indent -= 1 if indent < 0: indent = 0 func = findMatchingProfileEntry(key) if func == None: print "Missed Enter: " + key return timestamp = func[1] delta = long(tokens[TK_TIME]) - long(timestamp) if key in stats: stats[key][1] += 1 stats[key][2].append(long(delta)) stats[key][8].extend(func[2]) else: stats[key] = [key, 1, [long(delta)], 0.0, 0.0, 0.0, 0.0, 0.0, func[2]] openfuncs.remove(func) if len(openfuncs) > 0: parent = openfuncs[len(openfuncs) - 1] if key not in parent[2]: parent[2].append(delta) func = findMatchingStackEntry(key) if func == None: print "Missed Stack: " + key return func[2] = delta / 1000.0 else: indent += 1 spaces = "" for space in range(indent): spaces += " " stack.append([key, spaces, -1]) openfuncs.append([key, tokens[TK_TIME], []]) #if len(sys.argv) < 2: # sys.exit(1) openfuncs = [] stack = [] stats = {} output = [] leafs = [] filename = sys.argv[1] print "Analyzing profile...\n" print "Stage 1...\n" for line in open(filename + '.log', 'r'): processProfile(line) print "Stage 2...\n" for key in stats: stat = stats[key] total = sum(stat[2]) average = total / len(stat[2]) stat[3] = float(total) / 1000.0 stat[4] = 0.0 stat[5] = float(average) / 1000.0 stat[6] = float(max(stat[2])) / 1000.0 stat[7] = float(min(stat[2])) / 1000.0 for key in stats: stat = stats[key] childTotal = 0 for childTime in stat[8]: childTotal += childTime / 1000.0 if childTotal > stat[3]: print "WTH?" stat[4] = stat[3] - childTotal output.append(stat) if childTotal == 0: leafs.append(stat) print "Writing files...\n" rankfile = open(filename + '-call-ranking.log', 'w') rankfile.write("function, calls, total, totalown, average, maximum, minimum\n") for stat in sorted(output, lambda x, y: cmp(x[3], y[3]), reverse=True): rankfile.write(stat[0] + ', ' + str(stat[1]) + ', ' + str(stat[3]) + ', ' + str(stat[4]) + ', ' + str(stat[5]) + ', ' + str(stat[6]) + ', ' + str(stat[7]) + '\n') rankfile.close() leaffile = open(filename + '-leaf-ranking.log', 'w') leaffile.write("function, calls, total, totalown, average, maximum, minimum\n") for stat in sorted(leafs, lambda x, y: cmp(x[3], y[3]), reverse=True): leaffile.write(stat[0] + ', ' + str(stat[1]) + ', ' + str(stat[3]) + ', ' + str(stat[4]) + ', ' + str(stat[5]) + ', ' + str(stat[6]) + ', ' + str(stat[7]) + '\n') leaffile.close() stackfile = open(filename + '-call-stack.log', 'w') for func in stack: stackfile.write(func[1] + func[0] + " (" + str(func[2]) + "ms)\n") print "Postprocessing complete!"