Skip to main content

Profile specific bytecode operations in a target script

Project description

heavyops

heavyops allows you to identify performance bottlenecks related to specific bytecode instructions.

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

heavyops-0.1.0.tar.gz (3.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

heavyops-0.1.0-py3-none-any.whl (3.9 kB view details)

Uploaded Python 3

File details

Details for the file heavyops-0.1.0.tar.gz.

File metadata

  • Download URL: heavyops-0.1.0.tar.gz
  • Upload date:
  • Size: 3.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for heavyops-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c8ca8cf6d220aac565acada9e45fde76564cc492b1aacba8e2394d9647ec89e8
MD5 731f7a8179402c3e02ec442e41bbb232
BLAKE2b-256 b6d863257383c72f0056640fce94cb43564753e750970506948081744263c6e5

See more details on using hashes here.

File details

Details for the file heavyops-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: heavyops-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 3.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for heavyops-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4110dc678d5dcdb7db7d5b0b9dfcf816f3b7e6fee5dc56a2e549b16d515dfb70
MD5 32a57f190df33f38fa69ca4f45ae027b
BLAKE2b-256 27e115821fad203e77f643f9f3d4077eccc6a1b30a055ddbed73d42f2ec6ef97

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page