Skip to content

Python 3.13 - Complexity & Optimizations

Python 3.13 was released October 2024 with continued performance improvements and the experimental free-threading build.

Performance Improvements

Import Time Optimization

Several standard library modules have faster import times:

# Faster imports in 3.13
import typing      # ~33% faster
import email.utils # Faster
import enum        # Faster
import functools   # Faster
import threading   # Faster

textwrap.indent() Optimization

from textwrap import indent

# 3.13: ~30% faster for large input
large_text = "line\n" * 100000
result = indent(large_text, "  ")  # 30% faster than 3.12

Complexity Characteristics

All standard complexities preserved from 3.12:

Operation Complexity Status
list.append() O(1) amortized Unchanged
dict[key] O(1) avg Unchanged
set.add() O(1) amortized Unchanged
in (membership) O(n) or O(1) Type-dependent

New Language Features

Improved REPL

# Enhanced interactive interpreter
# - Multiline editing
# - Syntax highlighting  
# - Better history
# - Paste mode with F3

Improved Error Messages

# Better suggestions for misspelled names
colour = "red"
print(color)  # NameError now suggests 'colour'

# Better error for missing imports
json.loads(data)  # Suggests: import json

Experimental Features

Free-Threading (No GIL) - Experimental

# Experimental: Python 3.13t build
# Removes the Global Interpreter Lock
# Enables true parallelism in threads

# Must use special build:
# python3.13t or --disable-gil

import threading

# With free-threading, CPU-bound threads run in parallel
# Complexity unchanged, but actual parallelism possible

JIT Compiler - Experimental

# Experimental JIT compiler (copy-and-patch)
# Enable with: PYTHON_JIT=1
# Provides modest speedups for some workloads

Data Structure Performance

Lists

# Same O() complexity, continued optimizations
lst = list(range(1000000))

# append: O(1)* - same as 3.12
lst.append(999999)

# sort: O(n log n) - Timsort unchanged
lst.sort()

Dictionaries

# Same O() complexity
d = {i: i for i in range(1000)}

# lookup: O(1) avg - same
value = d[500]

# iteration: O(n) - same
for k, v in d.items():
    pass

locals() Semantics Change

# PEP 667: locals() now returns independent snapshots
def example():
    x = 1
    loc1 = locals()
    x = 2
    loc2 = locals()

    # 3.13: loc1['x'] == 1, loc2['x'] == 2
    # Previous: Both might show 2 (implementation-defined)

Deprecations

# Deprecated in 3.13:
# - asyncio.iscoroutinefunction() - use inspect.iscoroutinefunction()
# - Various legacy APIs

# Pending removal in 3.16:
# - array 'u' format code
# - ~bool (bitwise inversion on bool)

Recommendations

When to Upgrade

Upgrade to 3.13 if: - ✅ Want latest features - ✅ Need improved error messages - ✅ Testing free-threading builds - ✅ Python 3.12+ compatible codebase

Stay on 3.12 if: - ✅ Production stability priority - ✅ Package compatibility concerns - ✅ No need for new features

End of Life

  • Release: October 2024
  • Bugfix Support: Until October 2026
  • Security Support: Until October 2029