title: Performance overhead of nested functions in Python
body: <p>In Python 3.9, nested functions are surprisingly slower than normal functions, around 10% for my example.</p>
  <pre class="lang-py prettyprint-override"><code>from timeit import timeit
  
  def f():
      return 0
  
  def factory():
      def g():
          return 0
  
      return g
  
  g = factory()
  
  print(timeit(&quot;f()&quot;, globals=globals()))
  #&gt; 0.074835498
  print(timeit(&quot;g()&quot;, globals=globals()))
  #&gt; 0.08470309999999998
  </code></pre>
  <p><code>dis.dis</code> show the same bytecode, and the only difference that I've found was in function internal flags. Indeed, <code>dis.show_code</code> reveals that <code>g</code> has a flags <code>NESTED</code> while <code>f</code> has not.</p>
  <p>However, the flags can be removed, and it makes <code>g</code> as fast as <code>f</code>.</p>
  <pre class="lang-py prettyprint-override"><code>import inspect
  g.__code__ = g.__code__.replace(co_flags=g.__code__.co_flags ^ inspect.CO_NESTED)
  print(timeit(&quot;f()&quot;, globals=globals()))
  #&gt; 0.07321161100000001
  print(timeit(&quot;g()&quot;, globals=globals()))
  #&gt; 0.07439838800000001
  </code></pre>
  <p>I've tried to look at CPython code to understand how <code>CO_NESTED</code> flag could impact function execution, but I've found nothing. Is there any explanation to this performance difference relative to the <code>CO_NESTED</code> flag?</p>
  <p><strong>EDIT</strong>: Removing <code>CO_NESTED</code> flag seems also to have no impact on function execution, except the overhead, even when it has captured variable.</p>
  <pre class="lang-py prettyprint-override"><code>import inspect
  global_var = 40
  def factory():
      captured_var = 2
      def g():
          return global_var + captured_var
      return g
  g = factory()
  assert g() == 42
  
  g.__code__ = g.__code__.replace(co_flags=g.__code__.co_flags ^ inspect.CO_NESTED)
  assert g() == 42  # function still works as expected
  </code></pre>