Re: [streams] rsReader.readBatch(numberOfChunks)? rbsReader.read(view, { waitUntilDone: true })? (#320)

So, I was really curious why we were seeing ~210 ops/sec for the sync case, but upwards of 8000 ops/sec for the native promise case in Firefox.

I investigate with bz's help and we discovered that benchmark.js `deferred.resolve()` calls `setTimeout()`.  This means that using `deferred:true` in a synchronous fashion like we were will always be limited by the nested `setTimeout()` clamp of 4ms.  A 4ms clamp equals an upper bound of 250 ops/sec.  Add in some overhead and we can very easily see where the ~210 ops/sec was coming from.

I changed the sync case to do `Promise.resolve().then(function() { deferred.resolve() })`.  This uses the microtask schedule to break the nested `setTimeout()` loop.  This allows the sync case to run at 16000 ops/sec on my desktop.

Unfortunately, bluebird promises are unavoidably going to be limited by the `setTimeout()` clamp.  So that library still starts at ~210 ops/sec, but its performance characteristics allow it to do better than native at higher chunk size.

I put full test results in this google doc:

  https://docs.google.com/spreadsheets/d/1rl6mbD2z1x1bgJLD6y9KJLYWjppB7BujfiWvUMjYTVs/edit?usp=sharing

To summarize:

With a modest 4 chunks in the pipe, an async read() takes about 4 times longer to consume the pipe than it would with a sync read().  In absolute terms, the results show that the mobile devices I tested take longer than 1ms to consume this small 4-chunk pipe.

Based on these results I think we should consider providing a sync `read()` on `getReader()`.  The ReadableByteStream can offer an async `read(view)` on the `getByobReader()`.  I feel very strongly that we should not pessimize the common case to accommodate the aesthetics of the ByobReader optimization.

Note: I don't think this test shows any problem with Promises themselves.  I think the same issues would be present with callbacks.  Its just difficult to test the callback case without hitting the setTimeout() clamp.

Bonus Note: The test case now parses the URL to get values from the search params.  URLSearchParams is not available in Chrome yet, though, so this doesn't work there yet.  If anyone could provide a better solution I'd love to run these tests on Chrome as well.

---
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/320#issuecomment-91418297

Received on Friday, 10 April 2015 03:31:46 UTC