Open omarstreak opened 8 years ago
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:
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 https://github.com/cujojs/most/issues/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
Found this pretty nice example and explanation of Cold vs Hot (by RxJS) (in case you don't want to watch a video).
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?
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.
If someone will be giving this a try, they might be interested in similar work being done in Xstream: https://github.com/staltz/xstream/pull/14
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).
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.
@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.
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.