<story><title>Scalene: a high-performance, high-precision CPU and memory profiler for Python</title><url>https://github.com/emeryberger/scalene</url></story><parent_chain></parent_chain><comment><author>bawr_hszm</author><text>Sadly, relying on Python&amp;#x27;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&amp;#x27;t get delivered to the Python level until the interpreter comes back from C land, and it&amp;#x27;s possible to get stuck in C land even with pure Python code.&lt;p&gt;To wit:&lt;p&gt;&lt;pre&gt;&lt;code&gt;  $ python -m scalene trace.py
  f1 1.3852 312499987500000
  f2 1.2420 2812499962500000
  f3 1.5018 1.5
  trace.py: % of CPU time =  33.66% out of   4.13s.
  Line  | CPU %    |  [trace.py]
     1  |          | #!&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;env python
     2  |          | 
     3  |          | import time
     4  |          | 
     5  |          | def timed(f):
     6  |          |     def f_timed(*args, **kwargs):
     7  |          |         t = time.time()
     8  |          |         r = f(*args, **kwargs)
     9  |          |         t = time.time() - t
    10  |          |         print(&amp;#x27;%s %.4f %s&amp;#x27; % (f.__name__, t, r))
    11  |          |     return f_timed
    12  |          | 
    13  |          | @timed
    14  |          | def f1(n):
    15  |          |     s = 0
    16  |  17.99%  |     for i in range(n):
    17  |  81.29%  |         s += i
    18  |          |     return s
    19  |          | 
    20  |          | @timed
    21  |          | def f2(n):
    22  |   0.72%  |     return sum(range(n))
    23  |          | 
    24  |          | @timed
    25  |          | def f3(t):
    26  |          |     time.sleep(t)
    27  |          |     return t
    28  |          | 
    29  |          | if __name__ == &amp;#x27;__main__&amp;#x27;:
    30  |          |     f1(25_000_000)
    31  |          |     f2(75_000_000)
    32  |          |     f3(1.5)&lt;/code&gt;&lt;/pre&gt;</text></comment>
<story><title>Scalene: a high-performance, high-precision CPU and memory profiler for Python</title><url>https://github.com/emeryberger/scalene</url></story><parent_chain></parent_chain><comment><author>JackC</author><text>I love the idea of fast Python profilers that don&amp;#x27;t require modified source code to run.&lt;p&gt;One profiler I used recently which isn&amp;#x27;t mentioned in the readme is pyflame (developed at uber):&lt;p&gt;&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;pyflame.readthedocs.io&amp;#x2F;&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;pyflame.readthedocs.io&amp;#x2F;&lt;/a&gt;&lt;p&gt;pyflame likewise claims to run on unmodified source code and be fast enough to run in production, so it might be worth adding to the comparison. It generates flamegraphs, which greatly sped up debugging the other day when I needed to figure out why something was slow somewhere in a Django request-response callstack.</text></comment>