Skip to content

Commit f62ddee

Browse files
committed
Memoize various API and index functions for performance
1 parent 488ec1a commit f62ddee

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

‎lib/handlers.js‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ var aesprim = require('./aesprim');
22
var codegen = require('escodegen')
33
var slice = require('./slice');
44
var Sandbox = require('v8-sandbox').default;
5-
var _uniq = require('underscore').uniq;
5+
6+
var _ = require('underscore')
7+
var _uniq = _.uniq;
8+
var _memoize = _.memoize
69

710
// XXX: if this appears in a filter expression, this won't work
811
const _AT_SYMBOL_ = '_AT_SYMBOL_'
@@ -266,8 +269,10 @@ function _traverse(passable) {
266269

267270
function evaluate(expression, globals) {
268271
// Create sandbox JIT for expression evaluation
269-
if(!this.sandbox)
272+
if(!this.sandbox){
270273
this.sandbox = new Sandbox()
274+
this.sandbox.execute = _memoize(this.sandbox.execute, JSON.stringify)
275+
}
271276

272277
var code = 'setResult({value:' + expression + '})';
273278
var execute = {
@@ -298,7 +303,7 @@ function _parse_nullable_int(val) {
298303
return sval.match(/^-?[0-9]+$/) ? parseInt(sval) : null;
299304
}
300305

301-
function _replace_at(src){
306+
_replace_at = _memoize(function(src){
302307
var ast = aesprim.parse(src).body[0].expression;
303308

304309
function search_and_replace(_ast){
@@ -318,6 +323,6 @@ function _replace_at(src){
318323
}
319324

320325
return codegen.generate(search_and_replace(ast))
321-
}
326+
})
322327

323328
module.exports = Handlers;

‎lib/index.js‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ var assert = require('assert');
22
var dict = require('./dict');
33
var Parser = require('./parser');
44
var Handlers = require('./handlers');
5+
var _memoize = require('underscore').memoize;
56

67
var JSONPath = function() {
78
this.initialize.apply(this, arguments);
89
};
910

1011
JSONPath.prototype.initialize = function() {
1112
this.parser = new Parser();
13+
this.parser.parse = _memoize(this.parser.parse)
1214
this.handlers = new Handlers();
1315
};
1416

@@ -119,7 +121,8 @@ JSONPath.prototype.nodes = async function(obj, string, count) {
119121

120122
if (count === 0) return [];
121123

122-
var path = this.parser.parse(string);
124+
// slice to copy before manipulating:
125+
var path = this.parser.parse(string).slice();
123126
var handlers = this.handlers;
124127

125128
var partials = [ { path: ['$'], value: obj } ];
@@ -157,7 +160,7 @@ JSONPath.prototype.nodes = async function(obj, string, count) {
157160
return count ? matches.slice(0, count) : matches;
158161
};
159162

160-
JSONPath.prototype.stringify = async function(path) {
163+
JSONPath.prototype._stringify = _memoize(function(path) {
161164
assert.ok(path, "we need a path");
162165

163166
var string = '$';
@@ -192,9 +195,13 @@ JSONPath.prototype.stringify = async function(path) {
192195
}
193196

194197
return string;
198+
}, JSON.stringify)
199+
200+
JSONPath.prototype.stringify = function(path) {
201+
return this._stringify(path)
195202
}
196203

197-
JSONPath.prototype._normalize = function(path) {
204+
JSONPath.prototype._normalize = _memoize(function(path) {
198205
assert.ok(path, "we need a path");
199206

200207
if (typeof path == "string") {
@@ -245,7 +252,7 @@ JSONPath.prototype._normalize = function(path) {
245252
}
246253

247254
throw new Error("couldn't understand path " + path);
248-
}
255+
}, JSON.stringify)
249256

250257
function _is_string(obj) {
251258
return Object.prototype.toString.call(obj) == '[object String]';

0 commit comments

Comments
 (0)