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

Improving performance #198

Open
omarstreak opened this issue Apr 20, 2016 · 8 comments
Open

Improving performance #198

omarstreak opened this issue Apr 20, 2016 · 8 comments

Comments

@omarstreak
Copy link

I discovered Most (https://github.com/cujojs/most) a couple of days ago and the perf numbers look amazing. However, here at Streak we're all in on Kefir right now and don't want to migrate to a new stream library. My guess is that some of the techniques used in Most could be applied to Kefir.

I thought about implementing the performance improvements ourselves but figured I'd reach out to you to see if you're interested in taking on the project since you know Kefir better than anybody. I also understand you're very busy, so we'd be willing to sponsor the development.

Let me know what you think. If you want to take this conversation private you can reach me at omar@streak.com.

@rpominov
Copy link
Member

rpominov commented Apr 21, 2016

Most is amazing, yes! And I tried to port techniques used in it to Kefir at some point, but failed. As far as I understand the main reasons of that great performance are:

  1. Most's streams are "cold" by default, and Kefir's are "hot" (Sorry, I don't have a good link that describes what I mean. If you're not familiar with "hot vs cold observables", google it, or watch this video — this is the best I was able to find)
  2. Most more carefully optimized for JS engines

We can't "fix" #1 in Kefir because this will be a major API and semantics shift, it's better to recommend people to use Most/Rx if they want "cold" by default streams.

As for #2, in order to fix that a person need to have a deep understanding of JS engines, and I'm not such a person unfortunately. Actually Most (plus this talk) helped me to understand that this kind of optimizations isn't what I want to do, just because I have no idea what I'm doing.

See also cujojs/most#137

But If you or someone else will be able to apply some techniques from Most, I will love to merge such PRs.

Although it may turn out that in order to apply such optimizations one will need to rewrite Kefir from scratch, in which case I think it would de better if the rewritten version will live in a fork for a while. We could do something similar to what happening with RxJs 5 which coexist with older RxJS

@asaaki
Copy link

asaaki commented Apr 21, 2016

Found this pretty nice example and explanation of Cold vs Hot (by RxJS) (in case you don't want to watch a video).

@omarstreak
Copy link
Author

For #1 I do understand the difference between cold and hot observables and right now I prefer the developer productivity boost that default hot observables bring. If it becomes necessary from a performance standpoint I could see an explicit cold observable construction being added similar to lodash's _.chain.

You said that you failed at bringing in some of the techniques, what did you try and why did it fail?

@rpominov
Copy link
Member

rpominov commented Apr 21, 2016

I prefer the developer productivity boost that default hot observables bring.

I agree, I think this is the reason for libraries like Bacon or Kefir to exist. Cold vs Hot might be confusing.

If it becomes necessary from a performance standpoint I could see an explicit cold observable construction being added

I'm not sure I like this idea, we'll end up with another library like Rx or Most with two types of streams, and we already have at least two great libs like that.

You said that you failed at bringing in some of the techniques, what did you try and why did it fail?

I basically tried to analyze the call stack the engine dealing with when trying to deliver an event through chain of Observables, and find places where it can be optimized. Like make the engine inline a function, or don't deoptimize it. But I simply was't sure that I understood tools right etc. And I decided it's not for me. JS engines are complex and we have many of them and they evolve rapidly, so what was true today might became not true tomorrow even for a single engine. I decided it's better to just write sane code and hope for the best in that situation, at least for me.

@rpominov
Copy link
Member

If someone will be giving this a try, they might be interested in similar work being done in Xstream: staltz/xstream#14

@milankinen
Copy link

Actually I've a working PoC with multicast streams, written in plain JS. The goal of that PR is to make TS implementation split the required modifications into sensible steps and give some background/explanation fro them. Perf can indeed be fine-tuned into almost most's level and still have the multicast behaviour.

The performance results may be a bit misleading though: if stream has only one subscriber (like in perf tests) it is "unicast", thus extremely fast. When you apply another subscriber, then the derived step get's "multicasted" ad hoc and that slows down the execution a little bit. Luckily most of the application streams are unicast and there are only few points where the calculation diverges - hence I hope that the applied approach results in good performance in real apps as well.

(IMHO terms "hot" and "cold" are misleading. I'd rather use terms "unicast" and "multicast" streams).

@rpominov
Copy link
Member

rpominov commented Apr 27, 2016

Sounds great. I've suspected that "temperature" of observables isn't the key part of Most's perf. When an observable has only one subscriber the code path for delivering an event is very similar to if it was a unicast observable.

It would be great to have a "multicast by default" lib with performance similar to Most's. Would be great if it'll land in xstream, and I welcome any such work in Kefir.

And yeah, "cold" and "hot" have zero sense to me, I can't find any connection between the words and the meaning.

@omarstreak
Copy link
Author

@milankinen I'm not sure if you saw my offer to @rpominov earlier in the thread, but if you want to take a performance pass to Kefir we'd be willing to sponsor that development.

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

No branches or pull requests

4 participants