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

Performance ? #5

Open
MagixInTheAir opened this Issue Jan 28, 2018 · 6 comments

Comments

Projects
None yet
5 participants
@MagixInTheAir

MagixInTheAir commented Jan 28, 2018

Has any benchmark been done to help users know when using Greenlet is beneficial ? Also, knowing when not to use it would be a great gain.

Anyway, awesome work, thanks !

@developit

This comment has been minimized.

Owner

developit commented Jan 29, 2018

Not yet! I'd like to set up a test page that can be used to demonstrate which types of work are best suited to this technique. It could also be used for workerize.

@jonjaques

This comment has been minimized.

jonjaques commented Jan 30, 2018

Just out of curiosity, I see you are using Promise.resolve/then so this should work with synchronous functions too?

@hyanmandian

This comment has been minimized.

hyanmandian commented Jan 30, 2018

Yes @jonjaques , look at this example -> https://jsfiddle.net/cd8cnxvg/

@JamesMilnerUK

This comment has been minimized.

JamesMilnerUK commented May 25, 2018

I've been doing some benchmarking of Web Workers and also as an aside greenlet. This is the results I came to when excluding any logic except data transfer for the aysnc function (i.e. just returning the data).

This was run on my Dell XPS,Intel Core i7-4500 CPU @ 1.80GHz, 8GB of RAM, running Xubuntu, code was compiled to ES5 using Webpack 4 in 'production' mode.

n is the number of object keys, who's values are randomly generated from types of boolean, string, number, object and array.

Firefox:
spectacle q17861

Results explicitly are:

{ "n": 10, "create": 0, "await": 16 }
{ "n": 100, "create": 0, "await": 10 }
{ "n": 1000, "create": 2, "await": 10 }
{ "n": 10000, "create": 2, "await": 24 }
{ "n": 100000, "create": 0, "await": 172 }
{ "n": 1000000, "create": 2, "await": 2678 }

Chrome

spectacle g17861

{ "n": 10, "create": 1.0999999940395355, "await": 21.000000007916242 }
{ "n": 100, "create": 0.5999999993946403, "await": 6.4999999885912985 }
{ "n": 1000, "create": 0.8000000088941306, "await": 10.10000001406297 }
{ "n": 10000, "create": 0.9999999892897904, "await": 43.30000001937151 }
{ "n": 100000, "create": 0.9000000136438757, "await": 121.79999999352731 }
{ "n": 1000000, "create": 0.9999999892897904, "await": 1415.7000000122935 }

If anyone is interested transferables behave fairly constantly as we might expect (Chrome result):

spectacle e17861

Some remarks:

  • Chrome outperforms Firefox here. For larger inputs this is more noticeable, 2678ms vs 1415ms for 1,000,000 object keys
  • Objects with sub 10,000 entries for greenlet are sub ~50ms for transfer to and from the inline worker for Chrome and Firefox
  • Increase fairly linear after that point (~150ms for 100,000 vs ~1500ms for 1,000,000)

Hope that is useful to some people (@MagixInTheAir). I am writing a blog post more generally about Web Worker performance which I will leave here once I'm finished up with it.

For transparency, code and demo is here: https://jamesmilneruk.github.io/webworker-perf/

@developit

This comment has been minimized.

Owner

developit commented May 29, 2018

@JamesMilnerUK I took a look at the tests. Nice to have this data! I've got an open task to do exhaustive benchmarking of workers that I'll be diving into over the next month or so.

One thing I noticed - right now your benchmark never re-uses Workers (greenlet or manual). It might be good to split out the creation benchmark from the usage benchmark, avoiding any crazy overhead from instantiating 10k Workers (there would be a fair bit).

@JamesMilnerUK

This comment has been minimized.

JamesMilnerUK commented Jun 2, 2018

@developit, firstly thanks for this great little library, I've really enjoyed using it. Glad to hear the tests were useful :) Feel free to fork anything I've done if it's of use.

Regarding the instantiation of workers, only 1 worker is created per transfer benchmark (i.e. 10 workers are created in total, one for each n value) but this isn't factored into the cost of transfer:

You can see from the above data creation of a worker is fairly minimal (around 1ms). Having said this I never tested what would happen if you reused a worker for transfer, I'd imagine there might be some marginal performance benefit from doing that (plus you lose the cost of creation).

I wrote up my findings about everything a blog post you can see here: https://www.loxodrome.io/post/web-worker-performance/

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