Skip to content

Instantly share code, notes, and snippets.

@gregtatum
Created May 12, 2020 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregtatum/67f23c09d9daa4c628f87476944ecf50 to your computer and use it in GitHub Desktop.
Save gregtatum/67f23c09d9daa4c628f87476944ecf50 to your computer and use it in GitHub Desktop.
cProfile in Python to Gecko Profiler
import cProfile, pstats, StringIO, pdb, json
def func_a(n, l):
if (n > l / 2):
return func_b(n)
else:
return func_c(n)
def func_b(n):
return factorial_loop(n)
def func_c(n):
return factorial_loop(n)
def factorial_loop(n):
product = 1
for i in range(n):
product = product * (i+1)
return product
def factorial_recursive(n):
if n == 0:
return 1
else:
return n * factorial_recursive(n-1)
def run():
result = 0
# Run factorial in a loop
for x in range(300):
result += factorial_loop(x)
# Run a recursive factorial
for x in range(300):
result += factorial_recursive(x)
# Run a factorial with a different root
for x in range(3000):
result += func_a(x, 3000)
return result
def collect_profile():
profile = cProfile.Profile()
profile.enable()
run()
profile.disable()
return profile
def print_stats(profile):
stream = StringIO.StringIO()
ps = pstats.Stats(profile, stream=stream).sort_stats('cumulative')
ps.print_stats()
print(stream.getvalue())
def get_function_name(code):
if isinstance(code, str):
# This is a built-in function.
return code
else:
return code.co_name
def label(code):
if isinstance(code, str):
return ('(built-in)', 0, code) # built-in functions ('~' sorts at the end)
else:
return (code.co_filename, code.co_firstlineno, code.co_name)
def format_time(n):
s = "%s" % n
return s.ljust(10, ' ')
def get_inlinetime(entry):
return -entry.totaltime
def cprofile_to_gecko_profile(profile):
# https://github.com/python/cpython/blob/8d21aa21f2cbc6d50aab3f420bb23be1d081dac4/Modules/_lsprof.c#L502-L519
#
# _lsprof.profiler_entry(
# code=<code object factorial_recursive at 0x1082cd830, file "profiler.py", line 11>,
# callcount=45150,
# reccallcount=44850,
# totaltime=0.013555,
# inlinetime=0.013555,
# calls=[
# _lsprof.profiler_subentry(
# code=<code object factorial_recursive at 0x1082cd830, file "profiler.py", line 11>,
# callcount=44850,
# reccallcount=44551,
# totaltime=0.013457,
# inlinetime=0.013457
# )
# ]
# )
# The code attribute is taken from: https://github.com/python/cpython/blob/8d21aa21f2cbc6d50aab3f420bb23be1d081dac4/Include/code.h#L10
print("-----------|------------|------------------------")
print("total | inline | function")
print("-----------|------------|------------------------")
for entry in profile.getstats():
# stringArray = list()
# funcTable = {}
# stackTable = {}
print("%s | %s | %s" % (
format_time(entry.totaltime),
format_time(entry.inlinetime),
get_function_name(entry.code)
))
if entry.calls == None:
continue
for sub_entry in entry.calls:
print("%s | %s | - calls: %s" % (
format_time(sub_entry.totaltime),
format_time(sub_entry.inlinetime),
get_function_name(sub_entry.code)
))
profile = collect_profile()
cprofile_to_gecko_profile(profile)
# pdb.set_trace()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment