Persistent Storage Speed

After a couple of failed stabs at testing the relative speed of window.localStorage versus client-side databases, Ryan Grove and Can Duruk pointed out that my tests were not taking into account the asynchronous nature of the APIs. So, here is what I think is a more correct test of the relative speeds. Turns out it makes a huge difference when you test things correctly!

Why this matters:

On my MacBook Pro in desktop Safari, I'm seeing the DOM storage test take ~0.1ms per set of operations and ~10ms per set of operations for SQL storage. At that speed, the difference would be imperceptible to end-users. However, on my iPhone 3G, I'm seeing ~1ms per set of ops for DOM storage versus ~140ms for SQL. Now we're talking about a difference users might notice. This test shows me it pays to carefully consider whether the extra power of SQL is worth the speed cost on meek devices.

Iterations:

--
--
// TEST SETUP

function Timer() {
  this.start = 0
  this.duration = 0
}

Timer.prototype = {
  go : function () {
    this.duration = 0
    this.start = +new Date
  },
  stop : function (el) {
    var timer = this
    setTimeout(function () {
      timer.duration = +new Date - timer.start
      timer.start    = 0
      timer.write(el)
    }, 0)
  },
  write : function (el) {
    el.innerHTML = this.duration + 'ms'
  }
}

function getIters() {
  var sel = document.getElementById('iters')
  return +sel.options[sel.selectedIndex].value
}

// data
var someData = {
  'key'  : 'my-uuid',
  'name' : 'Fugly McFunston',
  'rank' : 'Junior Leftenant',
  'serial-number' : 'ABC123'
};

var lawnchair_dom = new Lawnchair({
  adaptor : 'dom'
});

var lawnchair_sql = new Lawnchair({
  table   : 'segdeha',
  adaptor : 'webkit'
});

function startDOM() {
  var iters = getIters(), i = 0, timer = new Timer(), el = document.getElementById('result-dom')
  el.innerHTML = '--'
  function run() {
    var myData
    lawnchair_dom.nuke()
    lawnchair_dom.save(someData, function() {
      lawnchair_dom.get('my-uuid', function(r) {
        myData = r
        lawnchair_dom.remove('my-uuid', function () {
            ++i
            if (i < iters)
              run()
            else
              timer.stop(el)
        })
      })
    })
  }
  timer.go()
  run()
}

function startSQL() {
  var iters = getIters(), i = 0, timer = new Timer(), el = document.getElementById('result-sql')
  el.innerHTML = '--'
  function run() {
    var myData
    lawnchair_sql.nuke()
    lawnchair_sql.save(someData, function() {
      lawnchair_sql.get('my-uuid', function(r) {
        myData = r
        lawnchair_sql.remove('my-uuid', function () {
            ++i
            if (i < iters)
              run()
            else
              timer.stop(el)
        })
      })
    })
  }
  timer.go()
  run()
}
Was this page useful to you? Loading...