The fastest memoizing and caching Python library written in Rust.

Overview

Cachebox

Cachebox is a Python library (written in Rust) that provides memoizations and cache implementions with different cache replecement policies.

This library is faster than other libraries and uses lower memory than them, you can see benchmarks here.

from cachebox import cached, TTLCache, LRUCache

# Keep coin price for no longer than a minute
@cached(TTLCache(maxsize=126, ttl=60))
def get_coin_price(coin_name):
    return web3_client.get_price(coin_name)

# Async functions are supported
@cached(LRUCache(maxsize=126))
async def get_coin_price(coin_name):
    return await async_web3_client.get_price(coin_name)

# You can pass `capacity` parameter.
# If `capacity` specified, the cache will be able to hold at least capacity elements without reallocating.
@cached(LRUCache(maxsize=126, capacity=100))
def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)

Page Content:

What is caching and why to use it?

Wikipeda:

In computing, caching improves performance by keeping recent or often-used data items in memory locations which are faster, or computationally cheaper to access, than normal memory stores. When the cache is full, the algorithm must choose which items to discard to make room for new data.

Researchgate:

Cache replacement policies play important roles in efficiently processing the current big data applications. The performance of any high performance computing system is highly depending on the performance of its cache memory.

Features

Pros:

  • Thread-safe (uses Rusts RwLock)
  • You can use it async and sync
  • Varius cache alghoritms (supports 8 cache alghoritms)
  • Super fast (is written in Rust language)
  • High performance

Cons:

  • Does not support iterating (for values, keys and items methods)

Supported:

  • Cache: Simple cache implemention with no policy and alghoritm.
  • FIFOCache: First In First Out cache implemention.
  • LFUCache: Least Frequently Used cache implemention.
  • RRCache: Random Replacement cache implemention.
  • LRUCache: Least Recently Used cache implemention.
  • MRUCache: Most Recently Used cache implemention.
  • TTLCache: LRU Cache Implementation With Per-Item TTL Value.
  • TTLCacheNoDefault: Time-aware Cache Implemention; With this cache, you can set its own expiration time for each key-value pair.

Installation

You can install cachebox from PyPi:

pip3 install -U cachebox

Tutorial

This package is very easy to use. You can use all implementions like a dictionary; they're supported all abc.MutableMapping methods. But there are some new methods you can see in examples.

At first, think about which alghoritm do you want to use? import and use it like a dictionary; In this examples we used LRUCache, TTLCache and TTLCacheNoDefault.

LRUCache example:

from cachebox import LRUCache

cache = LRUCache(10)
cache.insert("key", "value") # or cache["key"] = "value"
cache.delete("key") # or `del cache["key"]`

# `.clear()` method has new parameter `reuse`
# pass True to keeps the allocated memory for reuse (default False).
cache.clear(reuse=True)

And there are new methods for TTLCache and TTLCacheNoDefault. You can see those methods in these examples:

TTLCache example:

from cachebox import TTLCache

cache = TTLCache(10, ttl=2)
cache.insert(1, "value1") # or cache[1] = "value1"
cache.insert(2, "value2") # or cache[2] = "value2"
cache.insert(3, "value3") # or cache[3] = "value3"

# It works like `.get()` with the difference that it returns the expiration of item in seconds.
cache.get_with_expire(1)
# Output: ('value1', 1.971873426437378)

# It works like `.popitem()` with the difference that it returns the expiration of item in seconds.
cache.popitem_with_expire()
# Output: (1, 'value1', 1.961873426437378)

# It works like `.pop()` with the difference that it returns the expiration of item in seconds.
cache.pop_with_expire(2)
# Output: ('value2', 1.951873426437378)

# Calling this method removes all items whose time-to-live would have expired by time,
# and if `reuse` be True, keeps the allocated memory for reuse (default False).
cache.expire(reuse=False)

TTLCacheNoDefault example:

from cachebox import TTLCacheNoDefault

# TTLCacheNoDefault have not ttl parameter here.
cache = TTLCacheNoDefault(10)
cache.insert(1, "value1", ttl=10) # this key-pair is available for no longer than 10 seconds
cache.insert(2, "value2", ttl=2) # this key-pair is available for no longer than 2 seconds
cache.setdefault(3, "value3", ttl=6) # this key-pair is available for no longer than 6 seconds
cache.insert(4, "value4", ttl=None) # this key-pair never expire

# It works like `.get()` with the difference that it returns the expiration of item in seconds.
cache.get_with_expire(1)
# Output: ('value1', 9.971873426437378)

# It works like `.popitem()` with the difference that it returns the expiration of item in seconds.
cache.popitem_with_expire()
# Output: (2, 'value2', 1.961873426437378)

# It works like `.pop()` with the difference that it returns the expiration of item in seconds.
cache.pop_with_expire(4) 
# Output: ('value4', 0.0)

Frequently asked questions

What is the difference between TTLCache and TTLCacheNoDefault?

In TTLCache, you set an expiration time for all items, but in TTLCacheNoDefault, you can set a unique expiration time for each item.

TTL Speed
TTLCache One ttl for all items TTLCache is very faster than TTLCacheNoDefault
TTLCacheNoDefault Each item has unique expiration time TTLCacheNoDefault is very slow in inserting

Can we set maxsize to zero?

Yes, if you pass zero to maxsize, means there's no limit for items.

I use cachetools, how to change it to cachebox?

cachebox syntax is very similar to cachetools. Just change these items:

# If you use `isinstance` for cachetools classes, change those.
isinstance(cache, cachetools.Cache) -> isinstance(cache, cachebox.BaseCacheImpl)

# If you pass `None` to `cached()`, change it to `dict`.
@cachetools.cached(None) -> @cachebox.cached({})

# If you use `cache.maxsize`, change it to `cache.getmaxsize()`
cache.maxsize -> cache.getmaxsize()

TODO

  • Add benchmark for cacheing library

License

Copyright (c) 2024 aWolverP - MIT License

You might also like...
An easy-to-use SocketCAN library for Python and C++, built in Rust.

JCAN An easy-to-use SocketCAN library for Python and C++, built in Rust, using cxx-rs and pyo3. Warning: I have never used Rust before and I don't kno

Schemars is a high-performance Python serialization library, leveraging Rust and PyO3 for efficient handling of complex objects

Schemars Introduction Schemars is a Python package, written in Rust and leveraging PyO3, designed for efficient and flexible serialization of Python c

A library for python version numbers and specifiers, implementing PEP 440

PEP440 in rust A library for python version numbers and specifiers, implementing PEP 440 Not yet on crates.io due to PyO3/pyo3#2786. use std::str::Fro

Fast DNA manipulation for Python, written in Rust.

quickdna Quickdna is a simple, fast library for working with DNA sequences. It is up to 100x faster than Biopython for some translation tasks, in part

Fuzzy Index for Python, written in Rust. Works like error-tolerant dict, keyed by a human input.

FuzzDex FuzzDex is a fast Python library, written in Rust. It implements an in-memory fuzzy index that works like an error-tolerant dictionary keyed b

📦 A Python package manager written in Rust inspired by Cargo.
📦 A Python package manager written in Rust inspired by Cargo.

huak About A Python package manager written in Rust. The Cargo for Python. ⚠️ Disclaimer: huak is currently in its proof-of-concept (PoC) phase. Huak

📦 A Python package manager written in Rust inspired by Cargo.
📦 A Python package manager written in Rust inspired by Cargo.

huak About A Python package manager written in Rust. The Cargo for Python. ⚠️ Disclaimer: huak is currently in its Alpha phase. Huak aims to support a

An extremely fast Python linter, written in Rust.
An extremely fast Python linter, written in Rust.

Ruff An extremely fast Python linter, written in Rust. Linting the CPython codebase from scratch. ⚡️ 10-100x faster than existing linters 🐍 Installab

⚡ Blazing fast async/await HTTP client for Python written on Rust using reqwests

Reqsnaked Reqsnaked is a blazing fast async/await HTTP client for Python written on Rust using reqwests. Works 15% faster than aiohttp on average RAII

Releases(v1.0.19)
  • v1.0.19(Feb 29, 2024)

    Added

    • CHANGELOG file added to show you changes

    Fixed

    • Improve code stability
    • README.md file examples fixed
    • Add versions information to BENCHMARK.md file
    • __version__ and __author__ variables fixed

    Changed

    • Makefile test commands changed
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Feb 28, 2024)

Owner
Ali
Work on yourself ...
Ali
A CLI tool for CIs and build scripts, making file system based caching easy and correct (locking, eviction, etc.)

FS Dir Cache A CLI tool for CIs and build scripts, making file system based caching easy and correct (locking, eviction, etc.) When working on build s

Dawid Ciężarkiewicz 5 Aug 29, 2023
Punic is a remote caching CLI built for Apple's .xcframework

Punic is a remote caching CLI built for Carthage that exclusively supports Apple's .xcframeworks.

Shred Labs 26 Nov 22, 2022
Implemented reverse-engineered signature algorithm to successfully register with Apple's caching server.

View as English 项目描述 本项目通过逆向得到苹果缓存服务器的签名算法,并可以成功注册缓存服务。算法分为两种运行模式。 运行模式 直接运行(x64): 效率较高,但只支持64位CPU。已测试可运行在Windows/Linux/macOS上。 模拟器运行: 兼容性极高,支持所有CPU架构

null 6 Oct 27, 2023
Not the fastest terminal colors library. Don't even ask about size.

TROLOLORS Not the fastest terminal colors library. Don't even ask about size. Why? Don't even try to use it. But maybe you need to say to your boss th

Dmitriy Kovalenko 15 Oct 27, 2021
The fastest bloom filter in Rust. No accuracy compromises. Use any hasher.

b100m-filter The fastest bloom filter in Rust. No accuracy compromises. Use any hasher. Usage # Cargo.toml [dependencies] b100m-filter = "0.3.0" use b

null 4 Nov 19, 2023
This tool will profile official instances of OpenSUSE mirrorcache to determine the fastest repositories for your system

Mirror Magic tool to Magically make OpenSUSE Mirrors Magic-er This tool will profile official instances of OpenSUSE mirrorcache to determine the faste

Firstyear 30 Dec 22, 2022
Fastest GTF/GFF-to-BED converter chilling around

gxf2bed The fastest G{F,T}F-to-BED converter around the block! translates chr27 gxf2bed gene 17266470 17285418 . + . gene_id "ENSG00000151743"; chr27

Alejandro Gonzales-Irribarren 11 Feb 20, 2024
This is a simple command line application to convert bibtex to json written in Rust and Python

bibtex-to-json This is a simple command line application to convert bibtex to json written in Rust and Python. Why? To enable you to convert very big

null 3 Mar 23, 2022
Python package for topological data analysis written in Rust. Not limited to just H0 and H1.

Topological Data Analysis (TDA) Contents Installation Compiling from source Roadmap TDA is a python package for topological data analysis written in R

António Leitão 5 Feb 12, 2024
A fast, simple and lightweight Bloom filter library for Python, fully implemented in Rust.

rBloom A fast, simple and lightweight Bloom filter library for Python, fully implemented in Rust. It's designed to be as pythonic as possible, mimicki

Kenan Hanke 91 Feb 4, 2023