$A.util.json.encode

JavaScript performance comparison

Test case created by zerious

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  var $A = {
      util: {
          isUndefined: function (value) {
              return value === undefined;
          },
          isUndefinedOrNull: function (value) {
              return value == null;
          },
          isComponent: function (value) {
              return value instanceof Component;
          }
      }
  }
  
  function Component() {
      this.prop = 'prop'
  }
  
  function Json() {}
  
  Json.prototype.stringifyReplacer = function(key, value) {
      // We have to do this as JSON.stringify removes the property from
      // the resulted JSON string if its value is a function
      if (typeof value === 'function') {
          return value + '';
      }
  
      // Do not serialize components to the server
      if($A.util.isComponent(value)) {
          return null;
      }
  
      return value;
  };
  
  /**
   * Encodes an object into a JSON representation.
   *
   * @param {Object} obj The object to pass in the encoder.
   * @param {Object} replacer Optional function which passes key and value bound to the
   *            object, and returns a stringified value.
   * @param {String} whiteSpace Adds spaces or tabs to the resulting string. E.g. '\t'
   *            for tab
   */
  Json.prototype.encode = function(obj, replacer, whiteSpace) {
      if (typeof JSON !== "undefined") {
          // Protect ourselves from the evils of libraries like Prototype.js that decorate Array with extra methods such as .toJSON() and do the wrong thing!
          var oldArrayToJSON = Array.prototype.toJSON;
          var oldComponentToJSON = Component.prototype.toJSON;
          try {
              delete Array.prototype.toJSON;
              delete Component.prototype.toJSON;
  
              if ($A.util.isUndefinedOrNull(replacer)) {
                  return JSON.stringify(obj, Json.prototype.stringifyReplacer, whiteSpace);
              } else {
                  return JSON.stringify(obj, replacer, whiteSpace);
              }
          } finally {
              if (oldArrayToJSON) {
                  // assign property back to Array only if it exists so it doesn't add the addition toJSON property.
                  Array.prototype.toJSON = oldArrayToJSON;
              }
              if(oldComponentToJSON) {
                  Component.prototype.toJSON = oldComponentToJSON;
              }
          }
      }
  
      if (obj === undefined) {
          return 'null';
      }
  
      if (obj === null) {
          return 'null';
      }
  
      // Support the JSON.stringify() Object.toJSON() standard
      if (!$A.util.isUndefined(obj.toJSON)) {
          return arguments.callee(obj.toJSON());
      }
  
      switch (obj.constructor) {
          case String:
              return '"' + obj.replace(/\"/g, '\\"').replace(/\r|\n|\f/g, "\\n") + '"';
  
          case Array:
              var buf = [];
              for ( var i = 0; i < obj.length; i++) {
                  buf.push(arguments.callee(obj[i]));
              }
              return '[' + buf.join(',') + ']';
  
          case Object:
              var buf2 = [];
              for ( var k in obj) {
                  if (obj.hasOwnProperty(k)) {
                      // Recursively invoke encode() on both the property name and the
                      // value
                      buf2.push(arguments.callee(k) + ':' + arguments.callee(obj[k]));
                  }
              }
              return '{' + buf2.join(',') + '}';
  
          default:
              return obj.toString();
      }
  };
  
  /**
   * Encode a value as JSON after temporarily removing any `toJSON` overrides.
   *
   * @param {Any}      value    The value to encode.
   * @param {Function} replacer Optional function `JSON.stringify` replacer function.
   * @param {String}   space    Optional whitespace character(s) for formatting.
   */
  Json.prototype["encode2"] = (function(arrayProto, componentProto, stringify){
      /**
       * By default, use an encoder that is non-standard in 2 ways:
       *   1) It encodes functions as strings instead of omitting them.
       *   2) It encodes components as nulls instead of objects.
       */
      function encoder(k, v) {
          return typeof v === "function" ? v.toString() : (v instanceof Component ? null : v);
      }
  
      return function encode(value, replacer, space) {
          if (arrayProto.toJSON !== undefined || componentProto.toJSON !== undefined) {
              var arrayToJson = arrayProto.toJSON;
              var componentToJson = componentProto.toJSON;
              delete arrayProto.toJSON;
              delete componentProto.toJSON;
              try {
                  return stringify(value, replacer === undefined ? encoder : replacer, space);
              }
              finally {
                  if (arrayToJson) {
                      arrayProto.toJSON = arrayToJson;
                  }
                  if (componentToJson) {
                      componentProto.toJSON = componentToJson;
                  }
              }
          }
          return stringify(value, replacer === undefined ? encoder : replacer, space);
      };
  })(Array.prototype, Component.prototype, JSON.stringify);
  
  var a = [1, 2, 3, 4, 5];
  var b = 'Hello, World!';
  var c = new Component();
  var d = function () { console.log(b) };
  var e = { a: a, b: b, c: c, d: d };
  var j = new Json();
  

};
</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
old
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
j.encode(a); j.encode(b); j.encode(c); j.encode(d); j.encode(e);
pending…
new
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
j.encode2(a); j.encode2(b); j.encode2(c); j.encode2(d); j.encode2(e);
pending…

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

0 Comments