JSON search by key name

JavaScript performance comparison

Test case created by Evan Vosberg

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  (function (global) {
  
  	var rsimple = /^(?:(?:-?(?=[1-9]|0(?!\d))\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(?:true|false|null)|(?:"(?:[^"\\\\]*|\\\\["\\\\bfnrt\/]|\\\\u[0-9a-f]{4})*"))\s*:?\s*/,
  
  		ropen = /^(?:\[|\{)\s*/,
  
  		rnext = /^,\s*/,
  
  		rclose = /^(?:\]|\})\s*/;
  
  	function escapeRegexp(string) {
  		return (string)
  			.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, "\\$1");
  	}
  
  	function lexer(json) {
  		var part = "";
  
  		repl = function (all) {
  			part += all;
  			return "";
  		},
  
  		i = 0;
  
  		while (json.length && i >= 0) {
  			if (rsimple.test(json)) {
  				json = json.replace(rsimple, repl);
  			}
  			else if (ropen.test(json)) {
  				json = json.replace(ropen, repl);
  				i++;
  			}
  			else if (rclose.test(json) && i > 0) {
  				json = json.replace(rclose, repl);
  				i--;
  			}
  			else if (rnext.test(json) && i > 0) {
  				json = json.replace(rnext, repl);
  			}
  			else {
  				i = -1;
  			}
  		}
  
  		return part;
  	}
  
  	global.findInJSON = function (keyname, json, g) {
  		var rfind = new RegExp("\"" + escapeRegexp(keyname) + "\"\\s*:\\s*([\\s\\S]+)$", ""),
  			results = [];
  
  		function handle(json) {
  			var found = rfind.exec(json);
  
  			if (found) {
  				results.push(lexer(found[1]));
  
  				// Search global
  				if (g) {
  					handle(found[1]);
  				}
  			}
  		}
  
  		// Convert to JSON and start search
  		handle(json);
  
  		// Get results array from JSON string
  		return "[" + results.join(",") + "]";
  	};
  	
  	global.findInObject = function (keyname, object, g) {
  		var results = [];
  	
  		function handle(object) {
  			
  			for (var key in object) {
  				if (key === keyname) {
  					results.push(object[key]);
  					
  					if (!g) {
  						return;
  					}
  				}
  				
  				if (typeof object[key] === "object") {
  					handle(object[key]);
  				}
  			}
  		}
  	
  		handle(object);
  	
  		return results;
  	};
  
  }(this));
  
  var testDataObject = {
  	"module": [{
  		"exports": "Class",
  		"module": "class",
  		"author": "Evan Vosberg",
  		"copyright": "© 2012 by Evan Vosberg",
  		"info": "http://github.com/evanvosberg",
  		"license": "Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.",
  		"class": [{
  			"name": "Class",
  			"shortdesc": "Create a class object.",
  			"category": ["Utilities", "Example"],
  			"signature": [{
  				"since": "1.0",
  				"param": [{
  					"type": ["String"],
  					"name": "classname",
  					"shortdesc": "A scope name in dot natation to define the class global.",
  					"optional": true
  				}, {
  					"type": ["Array", "Class"],
  					"name": "superclass",
  					"shortdesc": "A class object or an array of class objects.",
  					"optional": true
  				}, {
  					"type": ["Object"],
  					"name": "properties",
  					"shortdesc": "An object of methods and properties for the speciefied class.",
  					"option": [{
  						"type": ["Function"],
  						"name": "constructor",
  						"shortdesc": "The class constructer which will be called on instantiate.",
  						"since": "1.0",
  						"optional": true
  					}]
  				}],
  				"return": ["Class"],
  				"title": "Class([classname] [, superclass], properties)"
  			}],
  			"description": {
  				"longdesc": "<p>Javascript doesn&#39;t have a Class system like Java, <code>Class()</code> simulates this.</p><h4>Setup a constuctor for the class</h4><p>If a method of the properties named <em>constructor</em>, it will be interpreted as the constructor method oncalling a new instance of the class. Also all constuctors of superclasses will be exectuted on calling anew instance of the class.</p><h4>Call overwritten inherited methods</h4><p>If a class overwrites a method of a superclass with an own method, you can call the original method insideof the new method in the following way <code>this._super(arg1, argN)</code> or <code>this._superApply(args)</code>.</p>"
  			},
  			"method": [{
  				"name": "_proxy",
  				"shortdesc": "This method is most useful for attaching event handlers to an element where the context is the current class instance.",
  				"signature": [{
  					"since": "1.0",
  					"param": [{
  						"type": ["String", "Function"],
  						"name": "function",
  						"shortdesc": "The function or the name of a function (from current instance) whose context will be changed to the current instance."
  					}],
  					"return": ["Function"],
  					"title": "_proxy(function)"
  				}],
  				"description": {
  					"longdesc-syntax": "md",
  					"longdesc": "<p>Additionally, <code>._proxy()</code> makes sure that even if you bind <code>jQuery.on()</code> the function with returned from <code>._proxy()</code> it will still unbind <code>jQuery.off()</code> the correct function, if passed the original.</p>"
  				}
  			}]
  		}],
  		"function": [{
  			"name": "Class.isClass",
  			"shortdesc": "Determine whether the given argument is an class object.",
  			"category": ["Utilities"],
  			"signature": [{
  				"since": "1.0",
  				"param": [{
  					"type": ["Function"],
  					"name": "function",
  					"shortdesc": "Object to test whether or not it is a function."
  				}, {
  					"type": ["Boolean"],
  					"name": "strict",
  					"shortdesc": "A boolean indication whether the class was created with Class().",
  					"optional": true
  				}],
  				"return": ["Boolean"],
  				"title": "Class.isClass(function [, strict])"
  			}],
  			"description": {
  				"longdesc-syntax": "md",
  				"longdesc": "<p>This method determines whether the argument is an class object.</p>"
  			}
  		}]
  	}]
  };
  var testDataJSON = JSON.stringify(testDataObject);

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
Loop source: JSON (needs to convert input)
this.findInObject("name", JSON.parse(testDataJSON), true);
pending…
Loop source: Object
this.findInObject("name", testDataObject, true);
pending…
Lexer source: Object (needs to convert input and output)
JSON.parse(this.findInJSON("name", JSON.stringify(testDataObject), true));
pending…
Lexer source: JSON (needs to convert output)
JSON.parse(this.findInJSON("name", testDataJSON, true));
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments