Mercurial > lbo > hg > memoize
view README.md @ 24:45b59350976f v0.1.4
Version: v0.1.4
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Fri, 16 Oct 2020 10:30:59 +0200 |
parents | c15379dd7de7 |
children | 9bcf7bab10a4 |
line wrap: on
line source
# memoize [![Docs.rs](https://docs.rs/memoize/badge.svg)](https://crates.io/crates/memoize) [![Crates.rs](https://img.shields.io/crates/v/memoize.svg)](https://crates.io/memoize) A `#[memoize]` attribute for somewhat simple Rust functions: That is, functions with one or more `Clone`-able arguments, and a `Clone`-able return type. That's it. Read the documentation (`cargo doc --open`) for the sparse details, or take a look at the `examples/`, if you want to know more: ```rust // From examples/test2.rs use memoize::memoize; #[memoize] fn hello(arg: String, arg2: usize) -> bool { arg.len()%2 == arg2 } fn main() { // `hello` is only called once here. assert!(! hello("World".to_string(), 0)); assert!(! hello("World".to_string(), 0)); // Sometimes one might need the original function. assert!(! memoized_original_hello("World".to_string(), 0)); } ``` This is expanded into (with a few simplifications): ```rust // This is obviously further expanded before compiling. lazy_static! { static ref MEMOIZED_MAPPING_HELLO : Mutex<HashMap<String, bool>>; } fn memoized_original_hello(arg: String, arg2: usize) -> bool { arg.len() % 2 == arg2 } fn hello(arg: String, arg2: usize) -> bool { let mut hm = &mut MEMOIZED_MAPPING_HELLO.lock().unwrap(); if let Some(r) = hm.get(&(arg.clone(), arg2.clone())) { return r.clone(); } let r = memoized_original_hello(arg.clone(), arg2.clone()); hm.insert((arg, arg2), r.clone()); r } ``` ## Further Functionality You can choose to use an [LRU cache](https://crates.io/crates/lru). In fact, if you know that a memoized function has an unbounded number of different inputs, you should do this! In that case, use the attribute like this: ```rust // From examples/test1.rs // Compile with --features=full use memoize::memoize; #[derive(Debug, Clone)] struct ComplexStruct { // ... } #[memoize(Capacity: 123)] fn hello(key: String) -> ComplexStruct { // ... } ``` Adding more caches and configuration options is relatively simple, and a matter of parsing attribute parameters. Currently, compiling will fail if you use a parameter such as `Capacity` without the feature `full` being enabled. ## Contributions ...are always welcome! This being my first procedural-macros crate, I am grateful for improvements of functionality and style. Please send a pull request, and don't be discouraged if it takes a while for me to review it; I'm sometimes a bit slow to catch up here :) -- Lewin