Wednesday, March 06, 2013 5:02 PM
With RX 2.0 should there be any concerns with using a subject to drive an observable chain through the use of continually calling a subjects OnNext method? I have provided my function with an observable generated by the subjects AsObservable method and afterwards am calling the Subjects OnNext method.
I have seen some posts where it is suggested that subjects should be avoided and I don't know if this is myth or fact. In my case, the use of a subject works quite well. My question is, am I incurring any performance overhead by using a subject. I am calling the subjects OnNext method anywhere between 100k - 300k times and it seems that as the level of nested Concat and SelectMany calls are made, performance goes down exponentially.
If anyone has any suggestions, I appreciate it.
Thursday, March 07, 2013 4:52 AM
The recommendation to not use subjects is due to design considerations, not performance. In general, you should only use subjects when you need to store an observable in a variable or field so that it can be imperatively "invoked" at a later time, like raising an event. If the invoker is stateful, then sometimes it makes sense to hold onto a subject; otherwise, subjects can often be avoided easily by using generator APIs such as Create, Generate, Range, Interval, Timer, etc.
(Note that subjects are used implicitly by some operators, such as Publish, though it's not a design issue because the IObserver<T> implementation is hidden from us and we only reference an IConnectableObservable<T>.)
In terms of performance, I believe that subjects are the best way to create event-like observable references, if that's what your design calls for.
Furthermore, they are actually designed to be faster than previous releases since the serialization restriction has been lifted, though taking advantage of that fact and invoking OnNext concurrently means that you can no longer apply Rx operators to the subject without potentially causing threading problems; i.e., don't call subject.OnNext(value) concurrently unless you call Synchronize first or simply subscribe directly to the subject without applying any Rx operators.
If your tests show that subjects are too slow for your usage, then it may simply be an issue with Rx or a garbage-collected platform in general.
> [snip] it seems that as the level of nested Concat and SelectMany calls are made, performance goes down exponentially.
I don't know about exponentially, but of course as you apply operators you're adding one or two additional stack frames though which all notifications must pass, allocating some new objects such as observers and disposables, and potentially adding some state, depending upon the nature of the operator of course.