Currently the ReplaySubject is a very versatile class that can perform 5 major use cases
- Replay-One. Caching and replaying the last value.
- Replay-Many. (i.e. a value > 1)
- Replay-Period. Cache data for a period of time for late subscribers
- Replay by count and time. A combination of caching by count and period.
- Replay-All. Cache and replay all values.
It seems to me that the most common usage* of Replay, "Replay(1)" incurs the cost of all the Scheduling and Buffering of the other implementations (Stopwatches, Queues, ImmutableLists of ScheduledObservers and the relevant checks).
My proposal is this: as the bufferSize
are readonly values of a ReplaySubject, a specialization of the inner workings of the ReplaySubject can be loaded at construction time. For example if the new Replay(1) constructor was called
then an internal implementation could be resolved that was specific and optimized for the behavior required by a Replay-one subject :
- Use ImmutableList<IObserver<T>> instead of ImmutableList<SchduedledObserver<T>>,
- no StopWatch,
- no internal Queue of cached values
- no Time and queue depth checks on every OnNext
For Replay(n) where n>1, then an implementation with an intenal queue could be used. Still this implementation would have no need for the ImmutableList<SchduedledObserver<T>>, StopWatch and the time checks on the OnNext call.
The two constructors that take a Window and a bufferSize+Window, could share an internal implemenation as I doubt there would be much perf difference between the two.
Finally the Reply-all behaviour where the parameterless constructor is used, could use the Replay-Many implementation passing Int.Max as a param, but this would still needlessly be calling the Trim method for each OnNext, so again is a candidate for specialization.
*In my opinion Replay(1) would be the most used operation of the ReplaySubject or the associated Replay extension method.