Write Test: IndexedDB vs localStorage vs webSQL (v53)

Revision 53 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="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"
        }
      }
      };
</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
local Storage write small data
scope.smallData.id = ++scope.i;
ls[scope.smallData.id] = JSON.stringify(scope.smallData);
ready
local Storage write large data
scope.largeData.id = ++scope.i;
ls[scope.largeData.id] = JSON.stringify(scope.largeData);
ready
Indexed DB write small data
var value;
scope.smallData.id = ++scope.i;
idb.put(scope.smallData, function(res){
  
});
ready
Indexed DB write large data
var value;
scope.largeData.id = ++scope.i;
idb.put(scope.largeData, function(res){
  
});
ready
Web SQL 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
Web SQL 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.