IndexedDB vs localStorage (v32)

Revision 32 of this benchmark created on


Preparation HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/idbwrapper/1.4.1/idbstore.min.js">
</script>
<script>
  var scope = {};

  // 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);');
  });

  // 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"
        }
      }
      };
  var oneMeg = "1234567890";
  for (var j = 1; j < 50000; j++) {
    oneMeg += "1234567890";
  }
  var fiveMeg = oneMeg + oneMeg + oneMeg + oneMeg + oneMeg;
  var tenMeg = fiveMeg + fiveMeg;
  var fiftyMeg = tenMeg + tenMeg + tenMeg + tenMeg + tenMeg;
</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 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));
ready
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));
ready
IDB write large data 1
// async test
var value;
scope.largeData.id = ++scope.i;
scope.largeData.sixtyMeg = fiftyMeg + tenMeg;
idb.put(scope.largeData, function(res) {
  deferred.resolve();
});
ready
IDB write large data 2
// async test
var value;
scope.largeData.id = ++scope.i;
scope.largeData.fiftyMeg = fiftyMeg;
idb.put(scope.largeData, function(res) {
  deferred.resolve();
});
ready
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();
    });
  });
});
ready
WebSQL read/write large data
// async test
var value;
scope.largeData.id = ++scope.i;
scope.largeData.oneMeg = oneMeg;
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();
    });
  });
});
ready

Revisions

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