{"id":15637114,"url":"https://github.com/aduth/memize","last_synced_at":"2025-04-05T15:08:38.323Z","repository":{"id":49947516,"uuid":"99758684","full_name":"aduth/memize","owner":"aduth","description":"Unabashedly-barebones memoization library with an aim toward speed","archived":false,"fork":false,"pushed_at":"2023-07-18T20:09:14.000Z","size":187,"stargazers_count":119,"open_issues_count":2,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-13T22:35:06.689Z","etag":null,"topics":["cache","memoization","memoize"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aduth.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-09T02:54:47.000Z","updated_at":"2024-10-31T03:10:31.000Z","dependencies_parsed_at":"2024-06-18T13:58:45.493Z","dependency_job_id":"44ec2ea7-0943-4855-9f65-c83acd10f907","html_url":"https://github.com/aduth/memize","commit_stats":{"total_commits":36,"total_committers":4,"mean_commits":9.0,"dds":"0.16666666666666663","last_synced_commit":"6866cf6fd5c9e087c3ddea6886a1af1471bb9052"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Fmemize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Fmemize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Fmemize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aduth%2Fmemize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aduth","download_url":"https://codeload.github.com/aduth/memize/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353746,"owners_count":20925329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","memoization","memoize"],"created_at":"2024-10-03T11:10:14.677Z","updated_at":"2025-04-05T15:08:38.305Z","avatar_url":"https://github.com/aduth.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Memize\n======\n\nMemize is a unabashedly-barebones memoization library with an aim toward speed.\n\nWhy use Memize?\n\n- 🚀 **It's very fast.** Implemented as a least recently used (LRU) cache, it's heavily optimized for scenarios where the function is called repeatedly with the same arguments.\n- 🔬 **It's tiny.** It weighs in at less than 0.3kb minified and gzipped, with no dependencies.\n- 🔀 **It supports common arguments patterns**, including multiple arguments and non-primitive arguments (by reference).\n\n## Example\n\nSimply pass your original function as an argument to Memize. The return value is a new, memoized function.\n\n```js\nfunction fibonacci( number ) {\n\tif ( number \u003c 2 ) {\n\t\treturn number;\n\t}\n\n\treturn fibonacci( number - 1 ) + fibonacci( number - 2 );\n}\n\nvar memoizedFibonacci = memize( fibonacci );\n\nmemoizedFibonnaci( 8 ); // Invoked, cached, and returned\nmemoizedFibonnaci( 8 ); // Returned from cache\nmemoizedFibonnaci( 5 ); // Invoked, cached, and returned\nmemoizedFibonnaci( 8 ); // Returned from cache\n```\n\n## Installation\n\nUsing [npm](https://www.npmjs.com/) as a package manager:\n\n```\nnpm install memize\n```\n\n## Usage\n\nMemize accepts a function to be memoized, and returns a new memoized function.\n\n```\nmemize( fn: Function, options: ?{\n\tmaxSize?: number\n} ): Function\n```\n\nOptionally, pass an options object with `maxSize` defining the maximum size of the cache.\n\nThe memoized function exposes a `clear` function if you need to reset the cache:\n\n```js\nmemoizedFn.clear();\n```\n\n## Benchmarks\n\nImplemented as a least recently used (LRU), Memize is heavily optimized for scenarios where the function is called repeatedly with the same arguments. In these scenarios, Memize outperformed most other memoization libraries at the time of initial publication.\n\nTo learn more about these benchmarks, important caveats, and how to run them yourself, refer to [`benchmark/README.md`](./benchmark/README.md).\n\n## How it works\n\nIf you haven't already, feel free to [glance over the source code](./index.js). The code is heavily commented and should help provide substance to the implementation concepts.\n\nMemize creates a [last-in first-out stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) implemented as a [doubly linked list](https://en.wikipedia.org/wiki/Doubly_linked_list). It biases recent access favoring real-world scenarios where the function is subsequently invoked multiple times with the same arguments. The choice to implement as a linked list is due to dramatically better performance characteristics compared to `Array#unshift` for surfacing an entry to the head of the list ([jsperf](https://jsperf.com/array-unshift-linked-list)). A downside of linked lists is inability to efficiently access arbitrary indices, but iterating from the beginning of the cache list is optimized by guaranteeing the list is sorted by recent access / insertion.\n\nEach node in the list tracks the original arguments as an array. This acts as a key of sorts, matching arguments of the current invocation by performing a shallow equality comparison on the two arrays. Other memoization implementations often use `JSON.stringify` to generate a string key for lookup in an object cache, but this benchmarks much slower than a shallow comparison ([jsperf](https://jsperf.com/lookup-json-stringify-vs-shallow-equality)).\n\nFinally, special care is made toward treatment of `arguments` due to engine-specific deoptimizations which can occur in V8 via [arguments leaking](https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments). Order is important here; we only create a shallow clone when necessary, after the cache has been checked, to avoid creating a clone unnecessarily if a cache entry exists. Looking at the code, you'd not be blamed for thinking that dropping the shallow clone would improve performance, but in fact it would _slow_ execution by approximately 60%. This is due to how the lingering `arguments` reference would carry over by reference (\"leaks\") in the node's `args` property. _**Update:** As of November 2019, engine improvements are such that `arguments` leaking does not have as dramatic an effect. However, my testing shows that the shallow clone still performs equal or better than referencing `arguments` directly, and as such the implementation has not been revised in order to achieve optimal performance in the most versions of V8._\n\n## License\n\nCopyright 2018-2020 Andrew Duthie\n\nReleased under the [MIT License](./LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduth%2Fmemize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faduth%2Fmemize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faduth%2Fmemize/lists"}