fast-memoize
Advanced tools
Comparing version 2.0.2 to 2.1.0
{ | ||
"name": "fast-memoize", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "Fastest memoization lib that supports N arguments", | ||
"main": "src/index.js", | ||
"scripts": { | ||
"test": "tape test/*.js --cov --reporter=spec", | ||
"test:lint": "standard \"src/**/*.js\" \"test/**/*.js\" \"benchmark/**/*.js\"", | ||
"test:coverage": "covert test/*.js", | ||
"test:cov": "npm run test:coverage", | ||
"test:karma": "karma start --singleRun", | ||
"test:all": "npm run test:lint && npm test && npm run test:karma", | ||
"test:saucelabs": "karma start saucelabs.karma.conf.js --singleRun", | ||
"build": "webpack", | ||
"benchmark": "node benchmark", | ||
"benchmark:cache": "node benchmark/cache", | ||
"benchmark:combination": "node benchmark/combination.js", | ||
"benchmark:recursive-all": "node benchmark/recursive-all.js", | ||
"benchmark:recursive-solo": "node --trace-opt benchmark/recursive-solo.js", | ||
"benchmark:serializer": "node benchmark/serializer", | ||
"benchmark:solo": "node benchmark/solo.js", | ||
"benchmark:strategy": "node benchmark/strategy", | ||
"benchmark:trace": "node --trace-inlining --trace-opt --trace-deopt benchmark/trace.js", | ||
"benchmark:v8-optimization-analysis": "node --allow_natives_syntax --expose_debug_as=VirtualMachine benchmark/v8-optimization-analysis.js", | ||
"lint": "eslint --fix \"src/**/*.js\" \"benchmark/**/*.js\"", | ||
"preversion": "npm run test:all", | ||
"version": "npm run build && git add dist/" | ||
"test": "jest", | ||
"test:all": "npm run lint && npm run test", | ||
"test:coverage": "covert test/*.js" | ||
}, | ||
"files": [ | ||
"README.md", | ||
"src/" | ||
], | ||
"repository": { | ||
@@ -24,3 +32,3 @@ "type": "git", | ||
"author": "Caio Gondim <me@caiogondim.com> (http://caiogondim.com)", | ||
"license": "ISC", | ||
"license": "MIT", | ||
"bugs": { | ||
@@ -32,26 +40,28 @@ "url": "https://github.com/caiogondim/fast-memoize/issues" | ||
"benchmark": "^2.0.0", | ||
"cli-table2": "^0.2.0", | ||
"covert": "^1.1.0", | ||
"karma": "^0.13.22", | ||
"karma-firefox-launcher": "^1.0.0", | ||
"karma-safari-launcher": "^1.0.0", | ||
"karma-sauce-launcher": "^1.0.0", | ||
"karma-tap": "^1.0.4", | ||
"karma-webpack": "^1.7.0", | ||
"eslint": "^3.12.1", | ||
"eslint-config-standard": "^6.2.1", | ||
"eslint-plugin-promise": "^3.4.0", | ||
"eslint-plugin-standard": "^2.0.1", | ||
"iMemoized": "0.0.10", | ||
"jest": "^17.0.3", | ||
"lodash": "^4.0.0", | ||
"logdown": "^1.2.5", | ||
"lru-cache": "^4.0.0", | ||
"memoizee": "^0.3.9", | ||
"mocha": "^2.5.3", | ||
"ramda": "^0.21.0", | ||
"standard": "^6.0.7", | ||
"tap": "^5.7.0", | ||
"tape": "^4.5.1", | ||
"underscore": "^1.8.3", | ||
"webpack": "^1.13.1" | ||
"memoizee": "^0.4.1", | ||
"ora": "^0.3.0", | ||
"ramda": "^0.22.1", | ||
"underscore": "^1.8.3" | ||
}, | ||
"standard": { | ||
"ignore": [ | ||
"/benchmark/addy-osmani.js" | ||
] | ||
"jest": { | ||
"testRegex": "\\.test\\.js$", | ||
"collectCoverage": true | ||
}, | ||
"eslintConfig": { | ||
"extends": "standard", | ||
"parserOptions": { | ||
"ecmaVersion": 6 | ||
} | ||
} | ||
} |
<img src="http://rawgit.com/caiogondim/fast-memoize/master/img/icon.svg" width="100%" /> | ||
# fast-memoize | ||
<h1 align="center">fast-memoize.js</h1> | ||
<img src="http://travis-ci.org/caiogondim/fast-memoize.js.svg?branch=master" alt="Travis CI"> <img src="http://david-dm.org/caiogondim/fast-memoize.js/dev-status.svg" alt="David DM"> [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) | ||
<div align="center"> | ||
<img src="http://travis-ci.org/caiogondim/fast-memoize.js.svg?branch=master" alt="Travis CI"> <img src="https://img.shields.io/badge/code%20style-standard-brightgreen.svg" alt="JS standard style"> | ||
</div> | ||
<br> | ||
@@ -14,5 +17,2 @@ > In computing, memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again. | ||
There are already very popular solutions for this problem, but they are **not | ||
fast enough** or accept **only one argument**. | ||
## Installation | ||
@@ -23,3 +23,3 @@ | ||
```shell | ||
npm install fast-memoize | ||
npm install fast-memoize --save | ||
``` | ||
@@ -78,8 +78,4 @@ | ||
There is already plenty of libraries that does memoization on JS world. | ||
[underscore](http://underscorejs.org/) and [lodash](https://lodash.com) provides | ||
it, but they don't accept more than one argument. | ||
[memoizee](https://www.npmjs.com/package/memoizee) is a very well written | ||
library that supports *N* arguments, but is not even close on performance to | ||
[lodash](https://lodash.com). | ||
For an in depth explanation on how this library was created, go read | ||
[this post on RisingStack](https://community.risingstack.com/the-worlds-fastest-javascript-memoization-library/). | ||
@@ -89,10 +85,4 @@ Below you can see a performance benchmark between some of the most popular libraries | ||
<img src="http://rawgit.com/caiogondim/fast-memoize/master/img/benchmark-chart.png" width="100%" /> | ||
<img src="http://rawgit.com/caiogondim/fast-memoize/master/img/benchmark.png" width="100%" /> | ||
[fast-memoize](https://github.com/caiogondim/fast-memoize) is faster than any | ||
other library but [lodash](https://lodash.com). The reason why is that | ||
[lodash](https://lodash.com) does not support *N* arguments and is very | ||
optimized to that unique use case. But even though, *fast-memoize* is the | ||
library that supports *N* that comes closer to it. | ||
To run the benchmark, clone the repo, install the dependencies and run `npm run benchmark`. | ||
@@ -108,27 +98,10 @@ ```shell | ||
## Support | ||
### Desktop browsers | ||
| ![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari/safari_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![Edge](https://raw.github.com/alrra/browser-logos/master/edge/edge_48x48.png) | ![Brave](https://raw.github.com/alrra/browser-logos/master/brave/brave_48x48.png) | | ||
| --- | --- | --- | --- | --- | --- | --- | | ||
| Latest | 8+ | Latest | Latest | Latest | Latest | Latest | | ||
### Mobile browsers | ||
| ![Chrome](https://raw.github.com/alrra/browser-logos/master/chrome/chrome_48x48.png) | ![Safari](https://raw.github.com/alrra/browser-logos/master/safari-ios/safari-ios_48x48.png) | ![Android Browser](https://raw.github.com/alrra/browser-logos/master/android/android_48x48.png) | ![IE](https://raw.github.com/alrra/browser-logos/master/internet-explorer/internet-explorer_48x48.png) | ![Firefox](https://raw.github.com/alrra/browser-logos/master/firefox/firefox_48x48.png) | ![Opera](https://raw.github.com/alrra/browser-logos/master/opera/opera_48x48.png) | ![UC](https://raw.github.com/alrra/browser-logos/master/uc/uc_48x48.png) | | ||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | | ||
| Latest | 6+ | 4.0+ | 8+ | Latest | Latest | Latest | | ||
### Server | ||
| <a href="https://nodejs.org"><img height=48 src="https://raw.githubusercontent.com/caiogondim/javascript-server-side-logos/master/node.js/standard/454x128.png"></a> | | ||
| --- | | ||
| 0.10+ ✔ | | ||
## Reference | ||
- https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments | ||
## Credits | ||
- Icon by Mary Rankin from the Noun Project | ||
- [Bullet train ZSH theme](https://github.com/caiogondim/bullet-train-oh-my-zsh-theme) | ||
--- | ||
[caiogondim.com](https://caiogondim.com) · | ||
GitHub [@caiogondim](https://github.com/caiogondim) · | ||
Twitter [@caio_gondim](https://twitter.com/caio_gondim) |
111
src/index.js
@@ -1,9 +0,9 @@ | ||
'use strict' | ||
// | ||
// Main | ||
// | ||
var cacheDefault = require('./cache') | ||
var serializerDefault = require('./serializer') | ||
function memoize (fn, options) { | ||
module.exports = function memoize (fn, options) { | ||
var cache | ||
var serializer | ||
var strategy | ||
@@ -22,23 +22,104 @@ if (options && options.cache) { | ||
function memoized () { | ||
if (options && options.strategy) { | ||
strategy = options.strategy | ||
} else { | ||
strategy = strategyDefault | ||
} | ||
return strategy(fn, { | ||
cache, | ||
serializer | ||
}) | ||
} | ||
// | ||
// Strategy | ||
// | ||
function isPrimitive (value) { | ||
return value == null || (typeof value !== 'function' && typeof value !== 'object') | ||
} | ||
function strategyDefault (fn, options) { | ||
function monadic (fn, cache, serializer, arg) { | ||
var cacheKey | ||
if (arguments.length === 1) { | ||
cacheKey = arguments[0] | ||
if (isPrimitive(arg)) { | ||
cacheKey = arg | ||
} else { | ||
cacheKey = serializer(arguments) | ||
cacheKey = serializer(arg) | ||
} | ||
if (!memoized._cache.has(cacheKey)) { | ||
memoized._cache.set(cacheKey, fn.apply(this, arguments)) | ||
if (!cache.has(cacheKey)) { | ||
var computedValue = fn.call(this, arg) | ||
cache.set(cacheKey, computedValue) | ||
return computedValue | ||
} | ||
return memoized._cache.get(cacheKey) | ||
return cache.get(cacheKey) | ||
} | ||
memoized._cache = cache.create() | ||
function variadic (fn, cache, serializer, ...args) { | ||
var cacheKey = serializer(args) | ||
if (!cache.has(cacheKey)) { | ||
var computedValue = fn.apply(this, args) | ||
cache.set(cacheKey, computedValue) | ||
return computedValue | ||
} | ||
return cache.get(cacheKey) | ||
} | ||
var memoized = fn.length === 1 | ||
? monadic | ||
: variadic | ||
memoized = memoized.bind( | ||
this, | ||
fn, | ||
options.cache.create(), | ||
options.serializer | ||
) | ||
arguments[0] = memoized | ||
return memoized | ||
} | ||
module.exports = memoize | ||
// | ||
// Serializer | ||
// | ||
function serializerDefault (...args) { | ||
return JSON.stringify(args) | ||
} | ||
// | ||
// Cache | ||
// | ||
class ObjectWithoutPrototypeCache { | ||
constructor () { | ||
this.cache = Object.create(null) | ||
} | ||
has (key) { | ||
return (key in this.cache) | ||
} | ||
get (key) { | ||
return this.cache[key] | ||
} | ||
set (key, value) { | ||
this.cache[key] = value | ||
} | ||
delete (key) { | ||
delete this.cache[key] | ||
} | ||
} | ||
const cacheDefault = { | ||
create: () => new ObjectWithoutPrototypeCache() | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
16
1
0
11423
6
211
103
1