Skip to main content

heavyops

heavyops identifies performance bottlenecks related to specific bytecode instructions.

Use it to find redundant object allocations, unexpected side effects of closures, and other inefficiencies in your Python code.

The project is based on sys.monitoring.

Installation

$ pip install heavyops

Example use case: side effects of closures

When a variable is captured by a closure, Python creates a cell object to hold the variable. This can lead to performance overhead. By tracking LOAD_DEREF instructions, you can identify functions that use closures and refactor them if necessary. For example:

class Foo:
    def __init__(self, lo, hi):
        self.lo = lo
        self.hi = hi

    def intersects(self, other):
        if isinstance(other, Foo):
            return self.lo < other.hi and other.lo < self.hi
        elif isinstance(other, list):
            # the following captures 'self' in a closure for the generator expression
            return any(self.intersects(item) for item in other)
        else:
            return False


for i in range(1000):
    Foo(1, 4).intersects(Foo(2, 5))

Even though the generator expression is not in a hot path, it captures self, leading to the creation of a cell object for self and the use of LOAD_DEREF instructions in the hot path:

$ python3 -m heavyops example.py 
3,814 / 94,467 tracked instructions

COUNT    | INSTRUCTION
--------------------------------------------------
   2,662 | LOAD_DEREF
     512 | MAKE_FUNCTION
     ...

COUNT    | LOCATION
--------------------------------------------------
   1,000 | example.py:8 intersects LOAD_DEREF
   1,000 | example.py:8 intersects LOAD_DEREF
     ...

This can be fixed by avoiding the generator expression, for example by using a for loop:

class Foo:
    def __init__(self, lo, hi):
        self.lo = lo
        self.hi = hi

    def intersects(self, other):
        if isinstance(other, Foo):
            return self.lo < other.hi and other.lo < self.hi
        elif isinstance(other, list):
            for item in other:
                if self.intersects(item):
                    return True
            return False

Usage

After installation an executable heavyops is available. Simply run it with the target script and its arguments:

heavyops [options] target_script.py [script_args...]

or as a module:

python3 -m heavyops [options] target_script.py [script_args...]

By default, it will report the following instructions:

  • MAKE_FUNCTION
  • BUILD_TUPLE
  • BUILD_LIST
  • BUILD_SET
  • BUILD_MAP
  • LOAD_DEREF

You can customize the instructions to track using on or more -i / --instructions flags.

heavyops -i MAKE_FUNCTION -i BUILD_LIST my_app arg1 arg2

You can restrict tracking to specific files using the -f / --file flag:

heavyops -f 'specific_file.py' my_app arg1 arg2

Metadata

Release files for heavyops 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for heavyops 0.3.0
File Size Uploaded
heavyops-0.3.0.tar.gz 4.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for heavyops 0.3.0
File Interpreter ABI Platform
heavyops-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 9.6 kB

Release files / heavyops-0.3.0.tar.gz

Download URL heavyops-0.3.0.tar.gz
Size 4.6 kB
Tags Source
SHA-256 checksum
How to use checksums
c3920c3b98f2bc1b76eb01b38cc366a85deea7e90f0a9d25102af9006631979f
BLAKE2b-256 checksum
How to use checksums
0bd5fefd496155b87e44953c62c4d8a9af1124c59dafae27de03e17b3a06aa25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / heavyops-0.3.0-py3-none-any.whl

Download URL heavyops-0.3.0-py3-none-any.whl
Size 5.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
df5d9291880e1629a7555d5bd173f1853a42f339ac713ff56c5d6bb1344fa274
BLAKE2b-256 checksum
How to use checksums
71496542fadb0b2a69671e23f4df32d0e5837773f031b28850860e6a3d20fe9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page