2023-01-13 22:10:01 +00:00
|
|
|
#!/usr/bin/python3
|
2022-09-29 23:23:10 +01:00
|
|
|
# This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
|
|
|
|
|
|
# Given a profile dump, this tool displays top functions based on the stacks listed in the profile
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
|
|
|
class Node:
|
|
|
|
def __init__(self):
|
|
|
|
self.function = ""
|
|
|
|
self.source = ""
|
|
|
|
self.line = 0
|
|
|
|
self.hier_ticks = 0
|
|
|
|
self.self_ticks = 0
|
|
|
|
|
|
|
|
def title(self):
|
|
|
|
if self.line > 0:
|
|
|
|
return "{} ({}:{})".format(self.function, self.source, self.line)
|
|
|
|
else:
|
|
|
|
return self.function
|
|
|
|
|
|
|
|
argumentParser = argparse.ArgumentParser(description='Display summary statistics from Luau sampling profiler dumps')
|
|
|
|
argumentParser.add_argument('source_file', type=open)
|
|
|
|
argumentParser.add_argument('--limit', dest='limit', type=int, default=10, help='Display top N functions')
|
|
|
|
|
|
|
|
arguments = argumentParser.parse_args()
|
|
|
|
|
|
|
|
dump = arguments.source_file.readlines()
|
|
|
|
|
|
|
|
stats = {}
|
|
|
|
total = 0
|
|
|
|
total_gc = 0
|
|
|
|
|
|
|
|
for l in dump:
|
|
|
|
ticks, stack = l.strip().split(" ", 1)
|
|
|
|
hier = {}
|
|
|
|
|
|
|
|
for f in reversed(stack.split(";")):
|
|
|
|
source, function, line = f.split(",")
|
|
|
|
node = stats.setdefault(f, Node())
|
|
|
|
|
|
|
|
node.function = function
|
|
|
|
node.source = source
|
|
|
|
node.line = int(line) if len(line) > 0 else 0
|
|
|
|
|
|
|
|
if not node in hier:
|
|
|
|
node.hier_ticks += int(ticks)
|
|
|
|
hier[node] = True
|
|
|
|
|
|
|
|
total += int(ticks)
|
|
|
|
node.self_ticks += int(ticks)
|
|
|
|
|
|
|
|
if node.source == "GC":
|
|
|
|
total_gc += int(ticks)
|
|
|
|
|
|
|
|
if total > 0:
|
|
|
|
print(f"Runtime: {total:,} usec ({100.0 * total_gc / total:.2f}% GC)")
|
|
|
|
print()
|
|
|
|
print("Top functions (self time):")
|
|
|
|
for n in sorted(stats.values(), key=lambda node: node.self_ticks, reverse=True)[:arguments.limit]:
|
|
|
|
print(f"{n.self_ticks:12,} usec ({100.0 * n.self_ticks / total:.2f}%): {n.title()}")
|
|
|
|
print()
|
|
|
|
print("Top functions (total time):")
|
|
|
|
for n in sorted(stats.values(), key=lambda node: node.hier_ticks, reverse=True)[:arguments.limit]:
|
|
|
|
print(f"{n.hier_ticks:12,} usec ({100.0 * n.hier_ticks / total:.2f}%): {n.title()}")
|