Write Test: IndexedDB vs localStorage vs webSQL (v60)

Revision 60 of this benchmark created on


Description

This tests localStorage performance against IndexedDB, both acting 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.

Preparation HTML

<script src="https://raw.github.com/jensarps/IDBWrapper/master/idbstore.js">
</script>
<script>
  var scope = {};

  // store setup
  var idb = new IDBObjectStore({
    dbName: 'jsperftestdb',
    storeName: 'jsperfteststore',
    dbVersion: '1.0',
    keyPath: 'id',
    autoIncrement: true,
    onStoreReady: function() {
      idb.clear();
    }
  });
  var ls = window.localStorage;
  ls.clear();


  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>

Setup

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
    };

Test runner

Ready to run.

Testing in
TestOps/sec
localStorage write small data
scope.smallData.id = ++scope.i;
ls[scope.smallData.id] = JSON.stringify(scope.smallData);
ready
localStorage write large data
scope.largeData.id = ++scope.i;
ls[scope.largeData.id] = JSON.stringify(scope.largeData);
ready
IDB write small data
scope.smallData.id = ++scope.i;
idb.put(scope.smallData);
ready
IDB write large data
scope.largeData.id = ++scope.i;
idb.put(scope.largeData);
ready
WebSQL write small data
// async test
scope.smallData.id = ++scope.i;
websql.transaction(function(tx) {
  tx.executeSql('INSERT INTO benchmark (id, value) VALUES (?, ?)', [scope.smallData.id, JSON.stringify(scope.smallData)]);
  deferred.resolve();
});
ready
WebSQL write large data
// async test
scope.largeData.id = ++scope.i;
websql.transaction(function(tx) {
  tx.executeSql('INSERT INTO benchmark (id, value) VALUES (?, ?)', [scope.largeData.id, JSON.stringify(scope.largeData)]);
  deferred.resolve();
});
ready

Revisions

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