Skip to content
Alan K edited this page May 14, 2014 · 14 revisions

I wanted a rough idea of where we are with performance. The data below suggest a few things:

  • Filer is currently about 2-3 (probably closer to 3) orders of magnitude slower than Node's fs API.
  • Filer performance in Chrome is not bound by IndexedDB (assuming the memory provider implementation is optimal, which is probably false), though chances are it will be once I start making performance improvements in Filer.
  • Based on the delays in get/put, it doesn't seem like caching will solve that particular performance issue since we would still need at least one get to make sure the root block is unchanged before we can use the cache.

See data below.

Chrome

?filer-providerType=indexeddb&iterations=20

mean	231.75 ms
min	177
max	322
med_abs_dev	11

?filer-providerType=memory&iterations=20

mean	260.45 ms
min	257
max	270
med_abs_dev	0.5

Firefox

?filer-providerType=indexeddb&iterations=20

mean	514 ms
min	469
max	600
med_abs_dev	14

?filer-providerType=memory&iterations=20

mean	274.6 ms
min	268
max	342
med_abs_dev	1

Node.js

mean: 0.27 ms
min: 0
max: 3
med_abs_dev: 0

High-level cost breakdown

This is the cost for each operation in the benchmark running in Chrome on the memory provider.

mkdir 49
stat 19
open 40
write 24
close 0
stat 28
open 25
read 10
close 0
unlink 43
rmdir 40

I wanted to know if get/put could account for slowness on the indexeddb provider. Costs for each operation running in Chrome on the indexeddb provider. Added timers for get and put provider operations.

get: 0.287ms
put: 0.339ms
put: 0.378ms
put: 0.288ms
timestamp_begin
get: 29.368ms
get: 0.237ms
get: 0.164ms
get: 0.196ms
get: 0.197ms
get: 0.214ms
put: 0.223ms
put: 0.170ms
put: 0.177ms
put: 0.201ms
mkdir 45 
get: 37.336ms
get: 0.166ms
get: 0.172ms
get: 0.152ms
stat 39
get: 0.344ms
get: 0.158ms
get: 0.136ms
get: 0.139ms
get: 0.116ms
put: 0.177ms
put: 0.209ms
put: 0.158ms
put: 0.173ms
open 4
get: 38.869ms
get: 0.202ms
put: 0.143ms
put: 0.168ms
put: 0.144ms
write 41
close 0
get: 54.417ms
get: 0.215ms
get: 0.128ms
get: 0.138ms
get: 0.123ms
get: 0.135ms
stat 56 
get: 0.341ms
get: 0.181ms
get: 0.178ms
get: 0.165ms
get: 0.158ms
get: 0.155ms
open 3 
get: 0.372ms
get: 0.189ms
read 1
close 0
get: 0.932ms
get: 3.881ms
get: 0.243ms
get: 0.178ms
get: 0.224ms
get: 0.263ms
put: 0.228ms
put: 0.232ms
unlink 10
get: 27.969ms
get: 0.182ms
get: 1.656ms
get: 0.143ms
get: 0.109ms
put: 0.146ms
put: 0.148ms
rmdir 33
timestamp_end

Investigation

Is internal queuing expensive?

@humphd suggested that internal queuing might be a performance hit. I wanted to see if that was true. In the cost breakdown above, close is inexpensive in spite of being invoked by queueOrRun.

asyncCallback

I wondered if asyncCallback might be causing the memory provider to be extra slow. I replaced asyncCallback in the memory provider with this

// var asyncCallback = require('async').nextTick;
var asyncCallback = function(fn) { fn.call(); };

All unit tests pass and the perf results look like this (100 iterations in Chrome):

mean	8.19 ms
min	5
max	16
med_abs_dev	1