localStorage vs WebSQL

JavaScript performance comparison

Revision 25 of this test case created

Info

This tests localStorage performance against IndexedDB, and WebSQL,all as an object store. localStorage tests contain JSON stringify/parse methods.

There's a performance penalty for the IDB tests though, as these operate on IDB via a wrapper, so there are are some additional function calls being made.

Additionally there is no JSON processing in WebSQL read, due to some errors.

Preparation code

<script>
  var scope = {};

  // store setup
  var ls = window.localStorage;
  ls.clear();

  var ss = window.sessionStorage;
  ss.clear();

  var oc = ocacheClear();

  function ocacheGet(c,key) { if (c.hasOwnProperty(key)) return(c[key]); return(null); }
  function ocacheSet(c,key,val) { c[key] = val; }
  function ocacheClear(c) { return(new Object()); }

  var websql = openDatabase('benchmark', '1.0', '', 1 * 1024 * 1024);
  websql.transaction(function(tx) {
    tx.executeSql('DROP TABLE IF EXISTS benchmark;');
    tx.executeSql('CREATE TABLE benchmark (id, value);');
  });

  // data setup
  var i = 0,
      lastnames = ['smith', 'miller', 'doe', 'frankenstein', 'furter'],
      firstnames = ['peter', 'john', 'frank', 'james'],
      dummyData = {
      "web-app": {
        "servlet": [{
          "servlet-name": "cofaxCDS",
          "servlet-class": "org.cofax.cds.CDSServlet",
          "init-param": {
            "configGlossary:installationAt": "Philadelphia, PA",
            "configGlossary:adminEmail": "ksm@pobox.com",
            "configGlossary:poweredBy": "Cofax",
            "configGlossary:poweredByIcon": "/images/cofax.gif",
            "configGlossary:staticPath": "/content/static",
            "templateProcessorClass": "org.cofax.WysiwygTemplate",
            "templateLoaderClass": "org.cofax.FilesTemplateLoader",
            "templatePath": "templates",
            "templateOverridePath": "",
            "defaultListTemplate": "listTemplate.htm",
            "defaultFileTemplate": "articleTemplate.htm",
            "useJSP": false,
            "jspListTemplate": "listTemplate.jsp",
            "jspFileTemplate": "articleTemplate.jsp",
            "cachePackageTagsTrack": 200,
            "cachePackageTagsStore": 200,
            "cachePackageTagsRefresh": 60,
            "cacheTemplatesTrack": 100,
            "cacheTemplatesStore": 50,
            "cacheTemplatesRefresh": 15,
            "cachePagesTrack": 200,
            "cachePagesStore": 100,
            "cachePagesRefresh": 10,
            "cachePagesDirtyRead": 10,
            "searchEngineListTemplate": "forSearchEnginesList.htm",
            "searchEngineFileTemplate": "forSearchEngines.htm",
            "searchEngineRobotsDb": "WEB-INF/robots.db",
            "useDataStore": true,
            "dataStoreClass": "org.cofax.SqlDataStore",
            "redirectionClass": "org.cofax.SqlRedirection",
            "dataStoreName": "cofax",
            "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
            "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
            "dataStoreUser": "sa",
            "dataStorePassword": "dataStoreTestQuery",
            "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
            "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
            "dataStoreInitConns": 10,
            "dataStoreMaxConns": 100,
            "dataStoreConnUsageLimit": 100,
            "dataStoreLogLevel": "debug",
            "maxUrlLength": 500
          }
        }, {
          "servlet-name": "cofaxEmail",
          "servlet-class": "org.cofax.cds.EmailServlet",
          "init-param": {
            "mailHost": "mail1",
            "mailHostOverride": "mail2"
          }
        }, {
          "servlet-name": "cofaxAdmin",
          "servlet-class": "org.cofax.cds.AdminServlet"
        },

        {
          "servlet-name": "fileServlet",
          "servlet-class": "org.cofax.cds.FileServlet"
        }, {
          "servlet-name": "cofaxTools",
          "servlet-class": "org.cofax.cms.CofaxToolsServlet",
          "init-param": {
            "templatePath": "toolstemplates/",
            "log": 1,
            "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
            "logMaxSize": "",
            "dataLog": 1,
            "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
            "dataLogMaxSize": "",
            "removePageCache": "/content/admin/remove?cache=pages&id=",
            "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
            "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
            "lookInContext": 1,
            "adminGroupID": 4,
            "betaServer": true
          }
        }],
        "servlet-mapping": {
          "cofaxCDS": "/",
          "cofaxEmail": "/cofaxutil/aemail/*",
          "cofaxAdmin": "/admin/*",
          "fileServlet": "/static/*",
          "cofaxTools": "/tools/*"
        },

        "taglib": {
          "taglib-uri": "cofax.tld",
          "taglib-location": "/WEB-INF/tlds/cofax.tld"
        }
      }
      };
</script>
<script>
Benchmark.prototype.setup = function() {
    scope.i = 0;
   
    scope.smallData = {
      'lastname': lastnames[Math.floor(Math.random() * 5)],
      'firstanme': firstnames[Math.floor(Math.random() * 4)],
      'dummyData': {}
    };
   
    scope.largeData = {
      'lastname': lastnames[Math.floor(Math.random() * 5)],
      'firstanme': firstnames[Math.floor(Math.random() * 4)],
      'dummyData': dummyData
    };
};
</script>

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
localStorage read/write small data
scope.smallData.id = ++scope.i;
ls.setItem(scope.smallData.id, JSON.stringify(scope.smallData));
var value = JSON.parse(ls.getItem(scope.smallData.id));
pending…
localStorage read/write large data
scope.largeData.id = ++scope.i;
ls.setItem(scope.largeData.id, JSON.stringify(scope.largeData));
var value = JSON.parse(ls.getItem(scope.largeData.id));
pending…
WebSQL read/write small data
// async test
var value;
scope.smallData.id = ++scope.i;
websql.transaction(function(tx) {
  tx.executeSql('INSERT INTO benchmark (id, value) VALUES (?, ?)', [scope.smallData.id, JSON.stringify(scope.smallData)], function(t, r) {
    t.executeSql('SELECT * FROM benchmark WHERE id=?', [scope.smallData.id], function(t1, r1) {

      deferred.resolve();
    });
  });
});
pending…
WebSQL read/write large data
// async test
var value;
scope.largeData.id = ++scope.i;
websql.transaction(function(tx) {
  tx.executeSql('INSERT INTO benchmark (id, value) VALUES (?, ?)', [scope.largeData.id, JSON.stringify(scope.largeData)], function(t, r) {
    t.executeSql('SELECT * FROM benchmark WHERE id=?', [scope.largeData.id], function(t1, r1) {

      deferred.resolve();
    });
  });
});
pending…
sessionStorage read/write small data
scope.smallData.id = ++scope.i;
ss.setItem(scope.smallData.id, JSON.stringify(scope.smallData));
var value = JSON.parse(ss.getItem(scope.smallData.id));
pending…
sessionStorage read/write large data
scope.largeData.id = ++scope.i;
ss.setItem(scope.largeData.id, JSON.stringify(scope.largeData));
var value = JSON.parse(ss.getItem(scope.largeData.id));
pending…
ocache read/write small data
scope.smallData.id = ++scope.i;
ocacheSet(oc,scope.smallData.id, scope.smallData);
var value = ocacheGet(scope.smallData.id);
pending…
ocache read/write large data
scope.largeData.id = ++scope.i;
ocacheSet(oc,scope.largeData.id, scope.largeData);
var value = ocacheGet(scope.largeData.id);
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. Here’s a list of current revisions for this page:

0 comments

Add a comment