Lawnchair vs taffy

Benchmark created by Elias on


Description

Compares two local JSON databases

Preparation HTML

<script>
  var user = {
   firstName: "Tila",
   lastName: "Tequilla",
   city: "Los Angeles",
   country: "USA"
  };
  
  var users = [];
  
  for (var i = 0; i < 10000; i++) {
   var userString = JSON.stringify(user);
   users.push(JSON.parse(userString));
  }
  
  
  
  
  var Lawnchair = function(a) {
   this.init(a)
  };
  Lawnchair.prototype = {
   init: function(a) {
    var b = {
     webkit: window.WebkitSQLiteAdaptor,
     gears: window.GearsSQLiteAdaptor,
     dom: window.DOMStorageAdaptor,
     cookie: window.CookieAdaptor,
     air: window.AIRSQLiteAdaptor,
     userdata: window.UserDataAdaptor,
     "air-async": window.AIRSQLiteAsyncAdaptor,
     blackberry: window.BlackBerryPersistentStorageAdaptor,
     couch: window.CouchAdaptor
    };
    this.adaptor = a.adaptor ? new b[a.adaptor](a) : new DOMStorageAdaptor(a);
    if (!JSON || !JSON.stringify) throw "Native JSON functions unavailable - please include http://www.json.org/json2.js or run on a decent browser :P";
   },
   save: function(a, b) {
    this.adaptor.save(a, b)
   },
   get: function(a, b) {
    this.adaptor.get(a, b)
   },
   exists: function(a) {
    this.adaptor.exists(a)
   },
   all: function(a) {
    this.adaptor.all(a)
   },
   remove: function(a, b) {
    this.adaptor.remove(a, b)
   },
   nuke: function(a) {
    this.adaptor.nuke(a);
    return this
   },
   paged: function(a, b) {
    this.adaptor.paged(a, b)
   },
   find: function(a, b) {
    var e = typeof a == "string" ?
    function() {
     return eval(a)
    } : a,
        d = this.adaptor.terseToVerboseCallback(b);
    this.each(function(a, b) {
     e(a) && d(a, b)
    })
   },
   each: function(a) {
    var b = this.adaptor.terseToVerboseCallback(a);
    this.all(function(a) {
     for (var d = a.length, c = 0; c < d; c++) b(a[c], c)
    })
   }
  };
  
  if (typeof TAFFY == "undefined" || !TAFFY) TAFFY = function(d) {
   var c = {
    template: null
   },
       f = TAFFY,
       b = f.isString(d) ? f.JSON.parse(d) : d,
       g = [],
       h = function(a, i) {
     i = i || c.template;
     if (!TAFFY.isNull(i)) for (var e = 0, f = a.length; e < f; e++) b[a[e]] = TAFFY.mergeObj(b[a[e]], i)
       },
       k = function() {
     g = [];
     for (var a = 0, i = b.length; a < i; a++) g[g.length] = a
       };
   k();
   var m = {
    pickTest: function(a) {
     var i = a.indexOf("!") === 0 ? !1 : !0;
     i || (a = a.substring(1, a.length));
     return {
      test: a == "equal" ? "is" : a == "notequal" ? "not" : a == "startswith" ? "starts" : a == "endswith" ? "ends" : a == "greaterthan" ? "gt" : a == "lessthan" ? "lt" : a == "regexppass" ? "regex" : a,
      mode: i ? {
       s: !0,
       f: !1
      } : {
       s: !1,
       f: !0
      }
     }
    },
    run: function(a, i, e, b) {
     return (a == "regex" ? e.test(i) : a == "lt" ? i < e : a == "gt" ? i > e : a == "lte" ? i <= e : a == "gte" ? i >= e : a == "starts" ? i.indexOf(e) === 0 : a == "ends" ? i.substring(i.length - e.length) == e : a == "like" ? i.toUpperCase().indexOf(e.toUpperCase()) >= 0 : a == "is" ? i == e : a == "has" ? f.has(i, e) : a == "hasAll" ? f.hasAll(i, e) : a == "length" ? m.length(i, e, b) : m[a](i, e)) ? b.s : b.f
    },
    length: function(a, i, e) {
     a = !f.isUndefined(a.length) ? a.length : !f.isUndefined(a.getLength) ? a.getLength() : 0;
     if (f.isObject(i)) for (var b in i) if (i.hasOwnProperty(b)) return e = m.pickTest(b), m.run(e.test, a, i[b], e.mode) ? !0 : !1;
     return a == i ? e.s : e.f
    }
   };
   (function() {
    for (var a in TAFFY) TAFFY.hasOwnProperty(a) && a.indexOf("is") === 0 &&
    function(a) {
     m["is" + a] = function(e, b) {
      return TAFFY["is" + a](e) == b ? !0 : !1
     }
    }(a.substring(2, a.length))
   })();
   var l = function(a, b) {
    var e = [];
    !f.isArray(a) && TAFFY.isNumber(a) ? e[e.length] = a : f.isArray(a) ? e = a : f.isObject(a) ? e = b(a) : !f.isArray(a) && !f.isNumber(a) && (e = g);
    return e
   },
       j = function(a) {
     var b = [0],
         e = "none";
     a += "";
     if (!f.isNull(a) && !f.isUndefined(a)) {
      for (var c = 0, d = a.length; c < d; c++) {
       var g = a.slice(c, c + 1);
       f.isNumeric(g) ? e != "number" ? (b[b.length] = g, e = "number") : b[b.length - 1] = b[b.length - 1] + "" + g : e != "string" ? (b[b.length] = g, e = "string") : b[b.length - 1] += g
      }
      c = 0;
      for (d = b.length; c < d; c++) f.isNumeric(b[c]) && (b[c] = parseFloat(b[c]))
     } else b[b.length] = null;
     return b
       },
       r = function(a) {
     var c = [],
         e = [];
     f.isString(a) ? e[0] = a : e = f.isObject(a) ? [a] : a;
     if (f.isArray(e)) {
      a = 0;
      for (var d = e.length; a < d; a++) if (f.isString(e[a])) c[c.length] = f.isString(b[0][e[a]]) ? {
       sortCol: e[a],
       sortDir: "asc",
       type: "string"
      } : {
       sortCol: e[a],
       sortDir: "asc",
       type: "number"
      };
      else if (f.isObject(e[a])) for (var g in e[a]) e[a].hasOwnProperty(g) && (c[c.length] = f.isString(b[0][e[a].sortCol]) ? {
       sortCol: g,
       sortDir: e[a][g],
       type: "string"
      } : {
       sortCol: g,
       sortDir: e[a][g],
       type: "number"
      })
     }
     return function(a, b) {
      for (var e = 0, d, g, o = 0, u = c.length; o < u; o++) if (e === 0) if (d = a[c[o].sortCol], g = b[c[o].sortCol], c[o].type == "string" && (d = f.isString(d) ? d.toLowerCase() : d, g = f.isString(g) ? g.toLowerCase() : g), c[o].sortDir == "desc") if (f.isNull(g) || f.isUndefined(g) || g < d) e = -1;
      else {
       if (f.isNull(d) || f.isUndefined(d) || d < g) e = 1
      } else if (c[o].sortDir == "logical") {
       d = j(d);
       g = j(g);
       for (var h = 0, l = g.length; h < l; h++) if (d[h] < g[h] && h < d.length) {
        e = -1;
        break
       } else if (d[h] > g[h]) {
        e = 1;
        break
       }
       d.length < g.length && e == 0 ? e = -1 : d.length > g.length && e == 0 && (e = 1)
      } else if (c[o].sortDir == "logicaldesc") {
       d = j(d);
       g = j(g);
       h = 0;
       for (l = g.length; h < l; h++) if (d[h] > g[h] && h < d.length) {
        e = -1;
        break
       } else if (d[h] < g[h]) {
        e = 1;
        break
       }
       d.length < g.length && e == 0 ? e = 1 : d.length > g.length && e == 0 && (e = -1)
      } else if (f.isNull(d) || f.isUndefined(d) || d < g) e = -1;
      else if (f.isNull(g) || f.isUndefined(g) || d > g) e = 1;
      return e
     }
       };
   return {
    TAFFY: !0,
    getLength: function() {
     return b.length
    },
    lastModifyDate: new Date,
    find: function(a, d) {
     var e = f.isArray(d) ? d : g;
     if (f.isFunction(a)) {
      for (var c = [], h = 0, l = e.length; h < l; h++) a(b[h], h) && (c[c.length] = e[h]);
      e = c
     } else for (var j in a) if (a.hasOwnProperty(j)) {
      var k = "is",
          n = "",
          r = j,
          s = {
        s: !0,
        f: !1
          },
          q = {};
      if (f.isObject(a[j])) for (var t in a[j]) {
       if (a[j].hasOwnProperty(t)) q = m.pickTest(t), k = q.test, s = q.mode, n = a[j][t]
      } else n = a[j];
      c = [];
      h = 0;
      for (l = e.length; h < l; h++) if (f.isArray(n) && k != "isSameArray" && k != "hasAll") if (s.s) for (var p = 0; p < n.length; p++) m.run(k, b[e[h]][r], n[p], s) && (c[c.length] = e[h]);
      else {
       q = 1;
       for (p = 0; p < n.length; p++) m.run(k, b[e[h]][r], n[p], s) || (q = 0);
       q == 1 && (c[c.length] = e[h])
      } else f.isFunction(n) && n(b[e[h]][r], h) ? c[c.length] = e[h] : m.run(k, b[e[h]][r], n, s) && (c[c.length] = e[h]);
      e = c
     }
     return e = f.gatherUniques(e)
    },
    remove: function(a) {
     a = l(a, this.find);
     for (var c = 0, e = a.length; c < e; c++) {
      if (!f.isNull(this.onRemove)) this.onRemove(b[a[c]]);
      b[a[c]] = "remove"
     }
     for (c = function() {
      for (var a = 0, e = b.length; a < e; a++) if (b[a] === "remove") return !0;
      return !1
     }; c();) {
      e = 0;
      for (var d = b.length; e < d; e++) if (b[e] === "remove") b.splice(e, 1), this.lastModifyDate = new Date
     }
     k();
     return a
    },
    insert: function(a) {
     a = TAFFY.isArray(a) ? a : [a];
     for (var d = 0; d < a.length; d++) {
      if (!f.isNull(this.onInsert)) this.onInsert(a[d]);
      b[b.length] = TAFFY.isNull(c.template) ? a[d] : TAFFY.mergeObj(c.template, a[d]);
      this.lastModifyDate = new Date;
      g[g.length] = b.length - 1
     }
     return [b.length - 1]
    },
    update: function(a, c) {
     for (var e =
     l(c, this.find), d = 0, g = 0, h = e.length; g < h; g++) {
      var j = e[g];
      if (!f.isNull(this.onUpdate)) this.onUpdate(a, b[j]);
      b[j] = f.mergeObj(b[j], a);
      d++
     }
     return e
    },
    get: function(a) {
     var c = [];
     a = l(a, this.find);
     for (var e = 0, d = a.length; e < d; e++) c[c.length] = b[a[e]];
     return c
    },
    first: function(a) {
     a = l(a, this.find);
     return a.length > 0 ? b[a[0]] : !1
    },
    last: function(a) {
     a = l(a, this.find);
     return a.length > 0 ? b[a[a.length - 1]] : !1
    },
    stringify: function(a) {
     return f.JSON.stringify(this.get(a))
    },
    orderBy: function(a) {
     if (b.length > 0) a = f.isFunction(a) ? a : r(a), b.sort(a), this.lastModifyDate = new Date
    },
    forEach: function(a, c) {
     for (var e = l(c, this.find), d, g = 0, h = e.length; g < h; g++) if (d = b[e[g]], d = a(d, e[g]), f.isObject(d)) if (TAFFY.isSameObject(d, TAFFY.EXIT)) break;
     else this.update(d, e[g])
    },
    sum: function(a, b) {
     var e = 0;
     this.forEach(function(b) {
      TAFFY.isNumeric(b[a]) && (e += b[a])
     }, b);
     return e
    },
    max: function(a, b) {
     var e, c = 0;
     this.forEach(function(b) {
      c == 1 && b[a] > e ? e = b[a] : c == 0 && (e = b[a], c = 1)
     }, b);
     return e
    },
    min: function(a, b) {
     var c, d = 0;
     this.forEach(function(b) {
      d == 1 && b[a] < c ? c = b[a] : d == 0 && (c = b[a], d = 1)
     }, b);
     return c
    },
    values: function(a, b) {
     var c = [];
     this.forEach(function(b) {
      c[c.length] = b[a]
     }, b);
     return c
    },
    uniqueValues: function(a, b) {
     var c = TAFFY([]);
     this.forEach(function(b) {
      c.find({
       value: b[a]
      }).length == 0 && c.insert({
       value: b[a]
      })
     }, b);
     return c.values("value")
    },
    config: {
     set: function(a, b) {
      c[a] = b;
      a == "template" && !TAFFY.isNull(b) && h(g, b)
     },
     get: function(a) {
      return c[a]
     }
    },
    applyTemplate: function(a, b) {
     var c = l(b, this.find);
     h(c, a)
    },
    onUpdate: null,
    onRemove: null,
    onInsert: null
   }
  }, TAFFY.typeOf = function(d) {
   var c =
   typeof d;
   c === "object" && (d ? typeof d.length === "number" && !d.propertyIsEnumerable("length") && typeof d.splice === "function" && (c = "array") : c = "null");
   return c
  }, TAFFY.JSON = function() {
   function d(b) {
    return b < 10 ? "0" + b : b
   }
  
   function c(b, d) {
    var h, k, m, l;
    h = RegExp('["\\\\\\x00-\\x1f\\x7f-\\x9f]', "g");
    var j;
    switch (typeof b) {
    case "string":
     return h.test(b) ? '"' + b.replace(h, function(b) {
      var a = f[b];
      if (a) return a;
      a = b.charCodeAt();
      return "\\u00" + Math.floor(a / 16).toString(16) + (a % 16).toString(16)
     }) + '"' : '"' + b + '"';
    case "number":
     return isFinite(b) ? String(b) : "null";
    case "boolean":
    case "null":
     return String(b);
    case "object":
     if (!b) return "null";
     if (typeof b.toJSON === "function") return c(b.toJSON());
     h = [];
     if (typeof b.length === "number" && !b.propertyIsEnumerable("length")) {
      l = b.length;
      for (k = 0; k < l; k += 1) h.push(c(b[k], d) || "null");
      return "[" + h.join(",") + "]"
     }
     if (d) {
      l = d.length;
      for (k = 0; k < l; k += 1) m = d[k], typeof m === "string" && (j = c(b[m], d)) && h.push(c(m) + ":" + j)
     } else for (m in b) typeof m === "string" && (j = c(b[m], d)) && h.push(c(m) + ":" + j);
     return "{" + h.join(",") + "}"
    }
    return ""
   }
   Date.prototype.toJSON =
  
   function() {
    return this.getUTCFullYear() + "-" + d(this.getUTCMonth() + 1) + "-" + d(this.getUTCDate()) + "T" + d(this.getUTCHours()) + ":" + d(this.getUTCMinutes()) + ":" + d(this.getUTCSeconds()) + "Z"
   };
   var f = {
    "\u0008": "\\b",
    "\t": "\\t",
    "\n": "\\n",
    "\u000c": "\\f",
    "\r": "\\r",
    '"': '\\"',
    "\\": "\\\\"
   };
   return {
    stringify: c,
    parse: function(b, c) {
     function d(b, f) {
      var j, k;
      if (f && typeof f === "object") for (j in f) Object.prototype.hasOwnProperty.apply(f, [j]) && (k = d(j, f[j]), k !== void 0 ? f[j] = k : delete f[j]);
      return c(b, f)
     }
     var f;
     if (/^[\],:{}\s]*$/.test(b.replace(/\\./g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) return f = eval("(" + b + ")"), typeof c === "function" ? d("", f) : f;
     throw new SyntaxError("parseJSON");
    }
   }
  }(), TAFFY.mergeObj = function(d, c) {
   var f = {},
       b;
   for (b in d) d.hasOwnProperty(b) && (f[b] = d[b]);
   for (b in c) c.hasOwnProperty(b) && (f[b] = c[b]);
   return f
  }, TAFFY.getObjectKeys = function(d) {
   var c = [],
       f;
   for (f in d) d.hasOwnProperty(f) && (c[c.length] = f);
   c.sort();
   return c
  }, TAFFY.isSameArray = function(d, c) {
   return TAFFY.isArray(d) && TAFFY.isArray(c) && d.join(",") == c.join(",") ? !0 : !1
  }, TAFFY.isSameObject = function(d, c) {
   var f = TAFFY;
   if (f.isObject(d) && f.isObject(c)) if (f.isSameArray(f.getObjectKeys(d), f.getObjectKeys(c))) for (var b in d) {
    if (d.hasOwnProperty(b) && !(f.isObject(d[b]) && f.isObject(c[b]) && f.isSameObject(d[b], c[b]) || f.isArray(d[b]) && f.isArray(c[b]) && f.isSameArray(d[b], c[b]) || d[b] == c[b])) return !1
   } else return !1;
   else return !1;
   return !0
  }, TAFFY.has = function(d, c) {
   var f = TAFFY,
       b = !0;
   if (f.isTAFFY(d)) return b = d.find(c), b.length > 0 ? !0 : !1;
   else switch (f.typeOf(d)) {
   case "object":
    if (f.isObject(c)) {
     for (var g in c) if (b === !0 && c.hasOwnProperty(g) && !f.isUndefined(d[g]) && d.hasOwnProperty(g)) b = f.has(d[g], c[g]);
     else return !1;
     return b
    } else if (f.isArray(c)) for (g = 0; g < c.length; g++) {
     if (b = f.has(d, c[g]), b === !0) return !0
    } else if (f.isString(c) && !TAFFY.isUndefined(d[c])) return !0;
    break;
   case "array":
    if (f.isObject(c)) for (var h = 0; h < d.length; h++) {
     if (b = f.has(d[h], c), b == !0) return !0
    } else if (f.isArray(c)) for (g = 0; g < c.length; g++) for (h = 0; h < d.length; h++) {
     if (b = f.has(d[h], c[g]), b == !0) return !0
    } else if (f.isString(c)) for (h = 0; h < d.length; h++) if (b = f.has(d[h], c), b == !0) return !0;
    break;
   case "string":
    if (f.isString(c) && c == d) return !0;
    break;
   default:
    if (f.typeOf(d) == f.typeOf(c) && d == c) return !0
   }
   return !1
  }, TAFFY.hasAll = function(d, c) {
   var f = TAFFY;
   if (f.isArray(c)) {
    for (var b = !0, g = 0, h = c.length; g < h; g++) if (b = f.has(d, c[g]), b == !1) return b;
    return !0
   } else return f.has(d, c)
  }, TAFFY.gatherUniques = function(d) {
   for (var c = [], f = 0; f < d.length; f++) {
    for (var b = !0, g = 0; g < c.length; g++) c[g] == d[f] && (b = !1);
    b == !0 && (c[c.length] = d[f])
   }
   return c
  }, function(d) {
   for (var c = 0; c < d.length; c++)(function(c) {
    TAFFY["is" + c] = function(b) {
     return TAFFY.typeOf(b) == c.toLowerCase() ? !0 : !1
    }
   })(d[c])
  }(["String", "Number", "Object", "Array", "Boolean", "Null", "Function", "Undefined"]), TAFFY.isNumeric = function(d) {
   for (var c = 0; c < d.length && !0 == !0; c++) if ("0123456789".indexOf(d.charAt(c)) == -1) return !1;
   return !0
  }, TAFFY.isTAFFY = function(d) {
   return TAFFY.isObject(d) && d.TAFFY ? !0 : !1
  }, TAFFY.EXIT = {
   EXIT: !0
  };
  localDB = TAFFY;
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
DB initialisation TAFFY
usersTaffy = new TAFFY(users);
ready
DB initialisation Lawnchair
usersLawnchair = new Lawnchair("users");

for (var i = 0; i < users.length; i++) {
 usersLawnchair.save(users[i], null);
}
ready

Revisions

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