Skip to content

Instantly share code, notes, and snippets.

@avli
Forked from markshannon/breakpoint_test.py
Last active September 15, 2023 14:04
Show Gist options
  • Save avli/9c1f69d55f6d3d28c4cc3da47a0dc511 to your computer and use it in GitHub Desktop.
Save avli/9c1f69d55f6d3d28c4cc3da47a0dc511 to your computer and use it in GitHub Desktop.
"""
An updated version of https://gist.github.com/markshannon/da7588db3c883dc2006a727a10e00ca5.
"""
import timeit
import sys
def foo():
for i in range(100_000):
if i == 50_000:
pass # Put breakpoint here
print("No debug")
print(timeit.timeit(foo, number=100))
DEBUGGER_ID = 0
if sys.version_info.minor >= 12:
print("PEP 669")
break_count = 0
def pep_669_breakpoint(code, line):
global break_count
if line == 11:
break_count += 1
else:
return sys.monitoring.DISABLE
sys.monitoring.use_tool_id(DEBUGGER_ID, "debugger")
sys.monitoring.register_callback(DEBUGGER_ID, sys.monitoring.events.LINE, pep_669_breakpoint)
sys.monitoring.set_local_events(DEBUGGER_ID, foo.__code__, sys.monitoring.events.LINE)
print(timeit.timeit(foo, number=100))
sys.monitoring.set_local_events(DEBUGGER_ID, foo.__code__, 0)
print("Break point hit", break_count, "times")
break_count = 0
# Use sys.settrace, this is about as fast as a sys.settrace debugger can be if written in Python.
print("sys.settrace")
foo_code = foo.__code__
def sys_settrace_breakpoint(frame, event, arg):
global break_count
if frame.f_code is not foo_code:
return None
if event == "line" and frame.f_lineno == 11:
break_count += 1
return sys_settrace_breakpoint
sys.settrace(sys_settrace_breakpoint)
print(timeit.timeit(foo, number=100))
sys.settrace(None)
print("Break point hit", break_count, "times")
@avli
Copy link
Author

avli commented Sep 15, 2023

Test run output (Python 3.12.0rc1):

No debug
0.2007869999997638
PEP 669
0.2106258000003436
Break point hit 100 times
sys.settrace
3.493140599999606
Break point hit 100 times

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment