Skip to main content

Smart Cache

PyPI pyversions PyPI version shields.io Maintenance

This is not production ready! There are still likely many bugs and there are several performance improvements which can be made

There are several Python caching alternatives, but there is only one to rule them all 💍.

Introducing smart cache—apply the @smart_cache decorator and all inputs with the same hash will be cached cross-run. Furthermore, the cache will be invalidated if the method bytecode OR the bytecode of method dependencies changes. This allows for fast rapid prototyping. You do not have to focus on which functions have been changed, Smart Cache does the work for you.

The only thing to pay attention to is that your functions are pure! This basically means that the same input arguments will always yield the same result. If this isn't the case, then don't include the @smart_cache decorator on that function—it can't be cached!

Installation

pip3 install smart-cache

Benchmarks

Let's benchmark the times between cached and non-cached versions of recursive fibonacci.

@smart_cache
def fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n - 1) + fib(n - 2)


def bad_fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return bad_fib(n - 1) + bad_fib(n - 2)


if __name__ == "__main__":
    start = time.time()
    cached_result = fib(40)
    end = time.time()

    print("total time cached: {:.2f}ms".format((end - start) * 1000))

    start = time.time()
    actual_result = bad_fib(40)
    end = time.time()
    print("total time uncached: {:.2f}ms".format((end - start) * 1000))

    difference = actual_result - cached_result
    print("difference: ", difference)

The first run (without any previous caching) we get times of

total time cached: 0.58ms
total time uncached: 31840.58ms
difference:  0

The second time will be even faster—we only need one lookup since fib(40) is cached. We get

total time cached: 0.48ms
total time uncached: 31723.69ms
difference:  0

Simple Example

Suppose we run

def abc():
    x = 2+2
    return x


@smart_cache
def tester():
    return 1 + abc()


if __name__ == "__main__":
    print(tester())

Only the first time we run this will results not be cached.

Suppose we make a modification to abc

def abc():
    x = 2+3
    return x

All caches will be invalidated. However, if abc were changed to

def abc():
    # this is a comment
    x = 2+2
    return x

The cache will not be invalidated because even though the code changes—none of the byte code changes.

Similary if we add another function xyz(),

def xyz(a_param):
    return a_param*2

The cache will also NOT be invalidated because although the bytecode of the file changes, the bytecode of neither the function tester nor its dependencies change.

Recursive Functions

Recursive functions also work as expected!

@smart_cache
def fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n - 1) + fib(n - 2)


if __name__ == "__main__":
    print(fib(6))

will run in O(n) time when it is first run and O(1) the time after that.

Release files for smart-cache 1.0.3

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

Source distribution (sdist)

Source distribution for smart-cache 1.0.3
File Size Uploaded
smart_cache-1.0.3.tar.gz 4.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for smart-cache 1.0.3
File Interpreter ABI Platform
smart_cache-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 9.3 kB

Release files / smart_cache-1.0.3.tar.gz

Download URL smart_cache-1.0.3.tar.gz
Size 4.7 kB
Tags Source
SHA-256 checksum
How to use checksums
417268ca753c5eedb55ac4ecdfd8192f1587cdaca477d3612db37c1ac4a6fecd
BLAKE2b-256 checksum
How to use checksums
ac9f1573f3d321f69736f350dbce734f8d371496e0bb7d563c9bf46ba7d5a1ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.1

Release files / smart_cache-1.0.3-py3-none-any.whl

Download URL smart_cache-1.0.3-py3-none-any.whl
Size 4.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c28a7911eea46e3096ea66e6f67e4e664bee9cfb2992f3fbb1bcc9214a5cc185
BLAKE2b-256 checksum
How to use checksums
a588475c3186456606816c80d695aa0109a8f51455ab6f322e7266d6f7c42e55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.1

Release history Release notifications | RSS feed

This release

1.0.3 This release

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.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