WRITE operations in IndexedDB vs localStorage vs webSQL

JavaScript performance comparison

Revision 3 of this test case created

Info

This test mirrors my modified version of this test: http://jsperf.com/indexeddb-vs-localstorage/15

I wanted a way to test the two distinct operations, READ and WRITE separately. I felt that testing them together was fatally flawed against async operations and didn't fairly highlight the strong points of the different storage mechanisms.

Preparation code

<script src="https://raw.github.com/jensarps/IDBWrapper/master/idbstore.js">
 
<script>
Benchmark.prototype.setup = function() {
   
   
      // store setup
      var idb = new IDBStore({
        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);');
      });
   
   
    var scope = {};
    scope.i = 0;
   
     // 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"
            }
          }
          };
   
    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
    };
   
    scope.smallData.id = ++scope.i;
    ls[scope.smallData.id] = JSON.stringify(scope.smallData);
    idb.put(scope.smallData);
    websql.transaction(function(tx) {
      tx.executeSql('INSERT INTO benchmark (id, value) VALUES (?, ?)', [scope.smallData.id, JSON.stringify(scope.smallData)])
    });
   
    scope.largeData.id = ++scope.i;
    ls[scope.largeData.id] = JSON.stringify(scope.largeData);
    idb.put(scope.largeData);
    websql.transaction(function(tx) {
      tx.executeSql('INSERT INTO benchmark (id, value) VALUES (?, ?)', [scope.largeData.id, JSON.stringify(scope.largeData)])
    });
};
</script>

Preparation code output