Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/plain.js
/profile.js
/weak-plain.js
/weak.js
/methods-plain.js
/methods.js
/lib/*.js
/ext/*.js
/normalizers/*.js
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
/.nyc_output
/coverage
/node_modules
node_modules/
npm-debug.log
/package-lock.json

/plain.js
/profile.js
/weak-plain.js
/weak.js
/methods-plain.js
/methods.js
/lib/*.js
/ext/*.js
/normalizers/*.js
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ memoized("foo", 3, "bar");
memoized("foo", 3, "bar"); // Cache hit
```

or via EsModules

```js
import memoize from "memoizee";

function fn(one, two, three) {
/* ... */
}

async function main() {
memoized = await memoize(fn);

memoized("foo", 3, "bar");
memoized("foo", 3, "bar"); // Cache hit
}

main();
```

**Note**: Invocations that throw exceptions are not cached.

### Configuration
Expand Down
78 changes: 39 additions & 39 deletions benchmark/fibonacci.js → benchmark/fibonacci.mjs
Original file line number Diff line number Diff line change
@@ -1,39 +1,38 @@
/* global console */
/* eslint no-console: 0, id-length: 0 */

"use strict";

// Simple benchmark for very simple memoization case (fibonacci series)
// To run it, do following in memoizee package path:
//
// $ npm install underscore lodash lru-cache secondary-cache
// $ node benchmark/fibonacci.js

var forEach = require("es5-ext/object/for-each")
, pad = require("es5-ext/string/#/pad")
, memoizee = require("..")
, underscore = require("underscore").memoize
, lodash = require("lodash").memoize
, lruCache = require("lru-cache")
, lruSecondary = require("secondary-cache/lib/lru-cache");

var now = Date.now
, time
, getFib
, lru
, memo
, total
, index = 3000
, count = 10
, i
, lruMax = 1000
, data = {}
, lruObj;

getFib = function (memoize, opts) {
var fib = memoize(function (x) { return x < 2 ? 1 : fib(x - 1) + fib(x - 2); }, opts);
// $ cd benchmark && npm install && cd ..
// $ node benchmark/fibonacci.mjs

import forEach from "es5-ext/object/for-each.js";
import pad from "es5-ext/string/%23/pad.js";
import memoizee from "../index.mjs";
import { memoize as underscore } from "underscore";
import lodash from "lodash/memoize.js";
import * as lruCache from "lru-cache";
import { Cache as lruSecondaryCache } from "secondary-cache";

var now = Date.now,
time,
lru,
memo,
total,
index = 3000,
count = 10,
i,
lruMax = 1000,
data = {},
lruObj;

async function getFib(memoize, opts) {
const fib = await memoize(function (x) {
return x < 2 ? 1 : fib(x - 1) + fib(x - 2);
}, opts);
return fib;
};
}

lru = function (x) {
var value = lruObj.get(x);
Expand All @@ -48,8 +47,8 @@ console.log("Fibonacci", index, "x" + count + ":\n");

total = 0;
i = count;
memo = await getFib(memoizee);
while (i--) {
memo = getFib(memoizee);
time = now();
memo(index);
total += now() - time;
Expand All @@ -58,8 +57,8 @@ data["Memoizee (object mode)"] = total;

total = 0;
i = count;
memo = await getFib(memoizee, { primitive: true });
while (i--) {
memo = getFib(memoizee, { primitive: true });
time = now();
memo(index);
total += now() - time;
Expand All @@ -68,8 +67,8 @@ data["Memoizee (primitive mode)"] = total;

total = 0;
i = count;
memo = await getFib(underscore);
while (i--) {
memo = getFib(underscore);
time = now();
memo(index);
total += now() - time;
Expand All @@ -78,8 +77,8 @@ data.Underscore = total;

total = 0;
i = count;
memo = await getFib(lodash);
while (i--) {
memo = getFib(lodash);
time = now();
memo(index);
total += now() - time;
Expand All @@ -88,8 +87,8 @@ data["Lo-dash"] = total;

total = 0;
i = count;
memo = await getFib(memoizee, { primitive: true, max: lruMax });
while (i--) {
memo = getFib(memoizee, { primitive: true, max: lruMax });
time = now();
memo(index);
total += now() - time;
Expand All @@ -98,8 +97,8 @@ data["Memoizee (primitive mode) LRU (max: 1000)"] = total;

total = 0;
i = count;
memo = await getFib(memoizee, { max: lruMax });
while (i--) {
memo = getFib(memoizee, { max: lruMax });
time = now();
memo(index);
total += now() - time;
Expand All @@ -108,8 +107,8 @@ data["Memoizee (object mode) LRU (max: 1000)"] = total;

total = 0;
i = count;
lruObj = new lruCache.LRUCache({ max: lruMax });
while (i--) {
lruObj = lruCache({ max: lruMax });
time = now();
lru(index);
total += now() - time;
Expand All @@ -118,8 +117,8 @@ data["lru-cache LRU (max: 1000)"] = total;

total = 0;
i = count;
lruObj = new lruSecondaryCache(lruMax);
while (i--) {
lruObj = lruSecondary(lruMax);
time = now();
lru(index);
total += now() - time;
Expand All @@ -131,6 +130,7 @@ forEach(
function (value, name, obj, currentIndex) {
console.log(currentIndex + 1 + ":", pad.call(value, " ", 5) + "ms ", name);
},
null,
function (a, b) { return this[a] - this[b]; }
function (a, b) {
return this[a] - this[b];
},
);
8 changes: 8 additions & 0 deletions benchmark/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"devDependencies": {
"lodash": "4.17.21",
"secondary-cache": "2.0.0",
"lru-cache": "11.0.0",
"underscore": "1.13.7"
}
}
16 changes: 7 additions & 9 deletions ext/async.js → ext/async.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

// Support for asynchronous functions

"use strict";

var aFrom = require("es5-ext/array/from")
, objectMap = require("es5-ext/object/map")
, mixin = require("es5-ext/object/mixin")
, defineLength = require("es5-ext/function/_define-length")
, nextTick = require("next-tick");
import aFrom from "es5-ext/array/from/index.js";
import objectMap from "es5-ext/object/map.js";
import mixin from "es5-ext/object/mixin.js";
import defineLength from "es5-ext/function/_define-length.js";
import nextTick from "next-tick";

var slice = Array.prototype.slice, apply = Function.prototype.apply, create = Object.create;

require("../lib/registered-extensions").async = function (tbi, conf) {
export default function asyncExtension(tbi, conf) {
var waiting = create(null)
, cache = create(null)
, base = conf.memoized
Expand Down Expand Up @@ -151,4 +149,4 @@ require("../lib/registered-extensions").async = function (tbi, conf) {
"clearasync", objectMap(oldCache, function (data) { return slice.call(data.args, 1); })
);
});
};
}
16 changes: 8 additions & 8 deletions ext/dispose.js → ext/dispose.mjs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Call dispose callback on each cache purge

"use strict";
import callable from "es5-ext/object/valid-callable.js";
import forEach from "es5-ext/object/for-each.js";
import async from "./async.mjs";
import promise from "./promise.mjs";

var callable = require("es5-ext/object/valid-callable")
, forEach = require("es5-ext/object/for-each")
, extensions = require("../lib/registered-extensions")
, apply = Function.prototype.apply;
var apply = Function.prototype.apply;

extensions.dispose = function (dispose, conf, options) {
export default function disposeExtension(dispose, conf, options) {
var del;
callable(dispose);
if ((options.async && extensions.async) || (options.promise && extensions.promise)) {
if ((options.async && async) || (options.promise && promise)) {
conf.on(
"deleteasync",
(del = function (id, resultArray) { apply.call(dispose, null, resultArray); })
Expand All @@ -24,4 +24,4 @@ extensions.dispose = function (dispose, conf, options) {
conf.on("clear", function (cache) {
forEach(cache, function (result, id) { del(id, result); });
});
};
}
26 changes: 11 additions & 15 deletions ext/max-age.js → ext/max-age.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,24 @@

// Timeout cached values

"use strict";

var aFrom = require("es5-ext/array/from")
, forEach = require("es5-ext/object/for-each")
, nextTick = require("next-tick")
, isPromise = require("is-promise")
, timeout = require("timers-ext/valid-timeout")
, extensions = require("../lib/registered-extensions");
import aFrom from "es5-ext/array/from/index.js";
import forEach from "es5-ext/object/for-each.js";
import nextTick from "next-tick";
import isPromise from "is-promise";
import timeout from "timers-ext/valid-timeout.js";
import async from "./async.mjs";
import promise from "./promise.mjs";

var noop = Function.prototype, max = Math.max, min = Math.min, create = Object.create;

extensions.maxAge = function (maxAge, conf, options) {
export default function maxAgeExtension(maxAge, conf, options) {
var timeouts, postfix, preFetchAge, preFetchTimeouts;

maxAge = timeout(maxAge);
if (!maxAge) return;

timeouts = create(null);
postfix =
(options.async && extensions.async) || (options.promise && extensions.promise)
? "async"
: "";
postfix = (options.async && async) || (options.promise && promise) ? "async" : "";
conf.on("set" + postfix, function (id) {
timeouts[id] = setTimeout(function () { conf.delete(id); }, maxAge);
if (typeof timeouts[id].unref === "function") timeouts[id].unref();
Expand Down Expand Up @@ -55,7 +51,7 @@ extensions.maxAge = function (maxAge, conf, options) {
preFetchAge = (1 - preFetchAge) * maxAge;
conf.on("get" + postfix, function (id, args, context) {
if (!preFetchTimeouts[id]) {
preFetchTimeouts[id] = "nextTick";
preFetchTimeouts[id] = "nextTick.js";
nextTick(function () {
var result;
if (preFetchTimeouts[id] !== "nextTick") return;
Expand Down Expand Up @@ -87,4 +83,4 @@ extensions.maxAge = function (maxAge, conf, options) {
preFetchTimeouts = {};
}
});
};
}
18 changes: 7 additions & 11 deletions ext/max.js → ext/max.mjs
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
// Limit cache size, LRU (least recently used) algorithm.

"use strict";
import toPosInteger from "es5-ext/number/to-pos-integer.js";
import lruQueue from "lru-queue";
import async from "./async.mjs";
import promise from "./promise.mjs";

var toPosInteger = require("es5-ext/number/to-pos-integer")
, lruQueue = require("lru-queue")
, extensions = require("../lib/registered-extensions");

extensions.max = function (max, conf, options) {
export default function maxExtension(max, conf, options) {
var postfix, queue, hit;

max = toPosInteger(max);
if (!max) return;

queue = lruQueue(max);
postfix =
(options.async && extensions.async) || (options.promise && extensions.promise)
? "async"
: "";
postfix = (options.async && async) || (options.promise && promise) ? "async" : "";

conf.on(
"set" + postfix,
Expand All @@ -29,4 +25,4 @@ extensions.max = function (max, conf, options) {
conf.on("get" + postfix, hit);
conf.on("delete" + postfix, queue.delete);
conf.on("clear" + postfix, queue.clear);
};
}
Loading