Sadly, relying on Python's signal handling is not enough to get robust profiling information the moment your code is spending a significant chunk of time outside of simple Python calls. This is because signals don't get delivered to the Python level until the interpreter comes back from C land, and it's possible to get stuck in C land even with pure Python code. To wit: $ python -m scalene trace.py f1 1.3852 31249998…
In short, a profiler that tells me that a program is spending a lot of time in C is not generally providing me particularly actionable information.
(In any event, the top-line report is that the Python part of the program only accounts for 33.66% of the execution time, which looks just about right.)