<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Python Developer Tooling Handbook – Performance</title>
    <link>https://pydevtools.com/handbook/topics/performance/</link>
    <description>The Python Developer Tooling Handbook is a comprehensive guide to Python development tools including uv, ruff, pytest, mypy, ty, and more.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 07 May 2026 13:56:14 -0400</lastBuildDate>
    
	  <atom:link href="https://pydevtools.com/handbook/topics/performance/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>How to profile a Python script with py-spy</title>
      <link>https://pydevtools.com/handbook/how-to/how-to-profile-a-python-script-with-py-spy/</link>
      <pubDate>Wed, 15 Apr 2026 08:23:33 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/how-to/how-to-profile-a-python-script-with-py-spy/</guid>
      <description>&lt;p&gt;This guide shows how to use &lt;a href=&#34;https://pydevtools.com/handbook/reference/py-spy/&#34;&gt;py-spy&lt;/a&gt; to profile a Python script. py-spy is a sampling profiler that runs in a separate process from the program it profiles, so it needs no &lt;code&gt;import&lt;/code&gt;, no decorator, and no restart. The result is a flame graph that shows where CPU time is actually spent.&lt;/p&gt;
&lt;div class=&#34;hx:overflow-x-auto hx:mt-6 hx:flex hx:rounded-lg hx:border hx:py-2 hx:ltr:pr-4 hx:rtl:pl-4 hx:contrast-more:border-current hx:contrast-more:dark:border-current hx:border-amber-200 hx:bg-amber-100 hx:text-amber-900 hx:dark:border-amber-200/30 hx:dark:bg-amber-900/30 hx:dark:text-amber-200&#34;&gt;
  &lt;div class=&#34;hx:ltr:pl-3 hx:ltr:pr-2 hx:rtl:pr-3 hx:rtl:pl-2&#34;&gt;&lt;svg height=1.2em class=&#34;hx:inline-block hx:align-middle&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34; fill=&#34;none&#34; viewBox=&#34;0 0 24 24&#34; stroke-width=&#34;2&#34; stroke=&#34;currentColor&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; d=&#34;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&#34;/&gt;&lt;/svg&gt;&lt;/div&gt;

  &lt;div class=&#34;hx:w-full hx:min-w-0 hx:leading-7&#34;&gt;
    &lt;div class=&#34;hx:mt-6 hx:leading-7 hx:first:mt-0&#34;&gt;This guide assumes &lt;a href=&#34;https://pydevtools.com/handbook/reference/uv/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv&lt;/a&gt; is installed. Follow the &lt;a href=&#34;https://pydevtools.com/handbook/how-to/how-to-install-uv/&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;uv installation guide&lt;/a&gt; first if needed.&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Install py-spy&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;install-py-spy&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#install-py-spy&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Install py-spy as a standalone tool on &lt;code&gt;PATH&lt;/code&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>profiling.sampling: Statistical Profiler in the Standard Library</title>
      <link>https://pydevtools.com/handbook/reference/profiling-sampling/</link>
      <pubDate>Thu, 07 May 2026 13:56:14 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/reference/profiling-sampling/</guid>
      <description>&lt;p&gt;&lt;code&gt;profiling.sampling&lt;/code&gt; is the statistical sampling profiler that ships with Python 3.15, developed under the codename Tachyon. It samples the call stacks of a Python process on a timer rather than instrumenting every call, and it can attach to a process that is already running by PID. The CLI is invoked as &lt;code&gt;python -m profiling.sampling&lt;/code&gt;, with &lt;code&gt;run&lt;/code&gt; and &lt;code&gt;attach&lt;/code&gt; as the two profiling entry points, &lt;code&gt;dump&lt;/code&gt; for a single stack snapshot, and &lt;code&gt;replay&lt;/code&gt; for converting saved binary profiles to other output formats.&lt;/p&gt;</description>
    </item>
    <item>
      <title>py-spy: Sampling Profiler for Python</title>
      <link>https://pydevtools.com/handbook/reference/py-spy/</link>
      <pubDate>Tue, 28 Apr 2026 21:54:51 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/reference/py-spy/</guid>
      <description>&lt;p&gt;py-spy is a sampling profiler for Python programs. It visualizes where a Python process spends its time without restarting the process or modifying its code. py-spy runs in a separate process from the program it profiles and reads stack information out of the target&amp;rsquo;s memory, which keeps overhead low enough that the project documents it as safe to use against production workloads.&lt;/p&gt;
&lt;h2&gt;When to Use py-spy&lt;span class=&#34;hx:absolute hx:-mt-20&#34; id=&#34;when-to-use-py-spy&#34;&gt;&lt;/span&gt;
    &lt;a href=&#34;#when-to-use-py-spy&#34; class=&#34;subheading-anchor&#34; aria-label=&#34;Permalink for this section&#34;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use py-spy when a Python process is already running and needs to be profiled in place: a web worker under load, a data-pipeline job mid-run, a stuck process that needs a stack dump, or any CPU-bound script whose profile should not be distorted by per-function tracing overhead. py-spy is a practical default for production CPU profiling because it requires no instrumentation and can be attached and detached at will. For line-by-line attribution inside a known hot function, reach for &lt;a href=&#34;https://github.com/pyutils/line_profiler&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;line_profiler&lt;/a&gt;; for memory rather than CPU, reach for &lt;a href=&#34;https://github.com/bloomberg/memray&#34;target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;memray&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sampling vs deterministic profilers: which should I use?</title>
      <link>https://pydevtools.com/handbook/explanation/sampling-vs-deterministic-profilers/</link>
      <pubDate>Thu, 07 May 2026 13:56:14 -0400</pubDate>
      <author>Tim Hopper</author>
      <guid>https://pydevtools.com/handbook/explanation/sampling-vs-deterministic-profilers/</guid>
      <description>&lt;p&gt;Two different designs dominate Python profiling, and they produce two different kinds of lies about your program. A &lt;strong&gt;deterministic profiler&lt;/strong&gt; intercepts every function call, records the entry and exit, and tallies the total. A &lt;strong&gt;sampling profiler&lt;/strong&gt; peeks at the call stack on a timer and counts how often each function shows up. Both give you a list of hot functions, and the list will not always agree.&lt;/p&gt;
&lt;p&gt;The difference matters because the choice changes what you can trust about the output.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
