C # Reactive Extensions - Memory Management and the Distinct Statement

Code example:

public static IObservable<Order> ObserveOrders(this IProxy proxy,IEqualityComparer<Order> distinctPerDayComparer ) { return Observable.FromEvent<Order>(ev => proxy.OrderUpdated += ev,ev => proxy.OrderUpdated -= ev) .Distinct(distinctPerDayComparer); } public class DistinctPerDayComparer : IEqualityComparer<Order> { public bool Equals(Order o1, Order o2) { if(o1.Id != o2.Id) return false; bool isSameDay = o1.Date.Day == o2.Date.Day; return isSameDay; } public int GetHashCode(Order o) { return o.Id.GetHashCode(); } } public class Order { public int Id { get; set; } public DateTime Date { get; set; } } 

Scenario:

Sequence:

  {id:1,D:'5/25/2016'}-{id:1,D:'5/25/2016'}-{id:2,D:'5/25/2016'}-{id:1 ,D:'5/26/2016'} 

Distinctive sequence:

  {id:1,D:'5/25/2016'}-{id:2,D:'5/25/2016'}-{id:1,D:'5/26/2016'} 

Now suppose this sequence is long; in fact, onComplete is never called.

How does the RX control it so that it does not hold all the individual elements in memory for comparison with?

I assume that it contains some storage for the elements in it. but I always thought that after onNext is called with the next element, the element is simply deleted.

However, if it determines which elements Rx uses for the EqualityComparer when calling the Distinct statement?

+2
source share
1 answer

If you look at the source code of Rx, you will find that different ones use a hashset and store the values ​​there. Your assumption that the element is simply located is incorrect.

If your order objects are heavy, you can use keyselector, and RX just saves that value in a hashset.

 .Distinct(o => Tuple.Create(o.id, o.Date), distinctPerDayComparer); 

then you need to change the PerDayComparer parameter

 public class DistinctPerDayComparer : IEqualityComparer<Tuple<int, DateTime>> { public bool Equals(Tuple<int, DateTime> o1, Tuple<int, DateTime> o2) { if(o1.Item1 != o2.Item1) return false; bool isSameDay = o1.Item2.Day == o2.Item2.Day; return isSameDay; } public int GetHashCode(Tuple<int, DateTime> o) { return o.Item1.GetHashCode(); } } 

did not test the code, but should be the starting one. Now save the Tuples until the sequence is complete, and not the Order objects.

Otherwise, you can use the Window function to group them and clear them according to a schedule, but then it is not really distinguishable for the entire observed sequence.

+2
source

Source: https://habr.com/ru/post/1203674/


All Articles