Skip to content

Conversation

@nolanlawson
Copy link
Member

This is a rewrite of #6031. Instead of having two separate implementations of changes(), I've implemented a new runBatchedCursor() routine that abstracts away two implementations:

  1. getAll()/getAllKeys()-based, for browsers that support it
  2. IDBCursor-based, for browsers that don't support getAll()/getAllKeys() or for queries where we need cursors (e.g. descending)

Mode 1 essentially works by fetching n changes for every batch, where n corresponds to limit in the changes() API. In the case of auto_compacted databases with no conflicts, and when we're not using opts.filter or opts.doc_ids, this means that we can accomplish changes() with a single batch (notably this applies to secondary indexes, giving them quite a perf boost).

In other cases, we may slightly overfetch, but I'd argue this is still better than fetching one-at-a-time, and that we're still honoring the user's preferences for memory consumption (communicated via limit). In cases where limit is -1/undefined we do not use Mode 1 since it would mean reading the whole DB into memory.

Mode 2 works like a classic IDBCursor, as we've done in the past. It's abstracted into Mode 1 by acting like a batched cursor where the batch size is 1.

I ran a benchmark using Firefox 50 and Chrome 55 on a MacBook Air, and got the following results for temp-views with 10 iterations:

Before After Improvement
Chrome 104826ms 51566ms 50.8%
Firefox 97959ms 55441ms 43.4%

So roughly, this makes secondary index creation in IDB about 2x faster in Chrome and Firefox. It also has the potential to make replication faster (when pulling from IDB databases) but I need to write a new benchmark to confirm it.

});
});
});

Copy link
Member Author

@nolanlawson nolanlawson Dec 20, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a new test to play it safe. This particular test would have failed in my previous implementation in #6031.

runBatchedCursor(bySeqStore, opts.since, opts.descending, limit, onBatch);
}

export default changes; No newline at end of file
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was uncomfortable with having so much changes logic in index.js so I moved it to its own file.

@daleharvey
Copy link
Contributor

That is a huge speedup, awesome job 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants