Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow results of createReadStream in the browser #21

Closed
tinchoz49 opened this issue Jun 4, 2020 · 8 comments
Closed

Slow results of createReadStream in the browser #21

tinchoz49 opened this issue Jun 4, 2020 · 8 comments

Comments

@tinchoz49
Copy link

Hi @vweevers, how are you?

I found something weird using level-mem (or level too) and createReadStream in the browser.

createReadStream in the browser takes 4 seconds to read 1000 elements but for example if I read the items one by one using get the performance increase. This is only happening in the browser.

I did a repository with my test: https://github.com/tinchoz49/level-bench

Results in my machine:

Node

# level: read by get
ok ~23 ms (0 s + 22597062 ns)

# level: createReadStream
ok ~17 ms (0 s + 16784238 ns)

# level-mem: read by get
ok ~16 ms (0 s + 15990506 ns)

# level-mem: createReadStream
ok ~15 ms (0 s + 14724392 ns)

wins: level-mem: createReadStream
ok ~104 ms (0 s + 104342327 ns)

Browser

# level: read by get
ok ~286 ms (0 s + 286250001 ns)

# level: createReadStream
ok ~4.45 s (4 s + 452095000 ns)

# level-mem: read by get
ok ~51 ms (0 s + 51350000 ns)

# level-mem: createReadStream
ok ~4.47 s (4 s + 468040000 ns)

wins: level-mem: read by get
ok ~9.46 s (9 s + 463925000 ns)
@vweevers
Copy link
Member

vweevers commented Jun 4, 2020

Might be due to the use of setTimeout(fn, 0) as a nexttick replacement in streams, at least for level-mem (level is a different story). And in general, browsers are slower because they have more work to do in between (unless you use a service worker) and they may throttle timers if the page gets backgrounded (in an inactive tab).

@tinchoz49
Copy link
Author

I'm going to check that.

@vweevers
Copy link
Member

vweevers commented Jun 4, 2020

You might also be interested in Level/community#70

@tinchoz49
Copy link
Author

ahh nice, I did something similar in hypercore holepunchto/hypercore#261

It really improves the performance of reading.

@tinchoz49
Copy link
Author

You right, I removed the setImmediate in the memdown iterator and the performance increased. Of course is not a soluton, just checking.

What I don't understand is that the get operation also does a setImmediate to schedule the callback read as a microtask but besides that is faster than AbstractLevelDOWN iterator.

I will keep checking, thanks!

@tinchoz49
Copy link
Author

Ok AbstractLevelDOWN iterator works great and the performance is about 100ms to read 1000 messages in the browser. So, next step is check what is doing the stream.

@tinchoz49
Copy link
Author

tinchoz49 commented Jun 4, 2020

Thanks @vweevers it was what you said, the Stream interface doing a nextTick for the internal maybeReadMore was slowing me down and it was of how webpack implement the process.nextTick.

I try doing this to check and the performance result was really impresive:

const queueMicrotask = require('queue-microtask');

if (typeof window !== 'undefined') {
  process.nextTick = function (fn) {
    var args = new Array(arguments.length - 1)
    if (arguments.length > 1) {
      for (var i = 1; i < arguments.length; i++) {
        args[i - 1] = arguments[i]
      }
    }

    queueMicrotask(() => fn(...args))
  }
}
# level: read by get
ok ~294 ms (0 s + 294485000 ns)

# level: createReadStream
ok ~77 ms (0 s + 77445000 ns)

# level: createReadStream (-maybeToRead nextTick)
ok ~62 ms (0 s + 61809999 ns)

# level-mem: read by get
ok ~32 ms (0 s + 31644999 ns)

# level-mem: createReadStream
ok ~25 ms (0 s + 24545000 ns)

# level-mem: createReadStream (-maybeReadMore nextTick)
ok ~12 ms (0 s + 12375001 ns)

wins: level-mem: createReadStream (-maybeReadMore nextTick)
ok ~725 ms (0 s + 725215000 ns)

@tinchoz49
Copy link
Author

-maybeReadMore nextTick was an experiment to test the read stream without doing a nexttick for the maybeReadMore. Similar to what it does from2

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

No branches or pull requests

2 participants