Vitalij
Vitalij

Reputation: 4625

Throttle operation resulting in a slow performance on window phone 7

I am building a WP7 application which heavily uses RX and I came across a problem. When adding Throttle with a value bigger that 20 ms it significantly reduces performance.

The snippet below pinpoints the issue:

var moveObs = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
                    h => this.MouseMove += h,
                    h => this.MouseMove -= h);

// Observe dragging
var yObs = (from x in moveObs
            select -(x.EventArgs.GetPosition(this).Y - _initY));

var result = yObs.SkipWhile(y => !_isDragging)
                 .Throttle(TimeSpan.FromMilliseconds(33));

result.TimeInterval()
      .Subscribe(x => Debug.WriteLine("Mouse move interval: " + x));

Here is output of the snippet:

'UI Task' (Managed): Loaded 'Microsoft.Devices.Sensors.dll'
The thread '<No Name>' (0x1e18) has exited with code 0 (0x0).
Mouse move interval: 80@00:00:04.1920000
Mouse move interval: -160@00:00:00.2900000
Mouse move interval: -126@00:00:00.6710000
The thread '<No Name>' (0x22a4) has exited with code 0 (0x0).
Mouse move interval: -90@00:00:01.0460000
The thread '<No Name>' (0x2514) has exited with code 0 (0x0).
Mouse move interval: -113@00:00:00.3250000
The thread '<No Name>' (0x270c) has exited with code 0 (0x0).
Mouse move interval: 108@00:00:12.1420000
The thread '<No Name>' (0x186c) has exited with code 0 (0x0).
Mouse move interval: 221@00:00:01.4860000

So to my understanding Throttle will create a thread from thread pool and won't block UI and it should be quite efficient, shouldn't it?

Question So why is performance so slow. I am a novice in RX so I am probably missing something here.

Edit

Here is another sample which reproduces the same issue:

var oneNumberPerSecond = Observable.Interval(TimeSpan.FromMilliseconds(10));

var lowNums = from n in oneNumberPerSecond
              select n;


lowNums.Throttle(TimeSpan.FromMilliseconds(100))
       .TimeInterval()
       .Subscribe(lowNum => Debug.WriteLine(lowNum));

In my understanding this should print a number every 100 ms, however it doesn't print any.

Upvotes: 1

Views: 268

Answers (1)

Asti
Asti

Reputation: 12687

It's not that it's slow - what you've described is exactly the behavior of Throttle.

Throttle produces a value when the stream stops producing a value for the specified duration.

Let me break down your repro:

var oneNumberPerSecond = Observable.Interval(TimeSpan.FromMilliseconds(10));

This is a cold observable which produces a value every 10 msecs.

var lowNums = from n in oneNumberPerSecond
              select n;

This does nothing really. It's equivalent to oneNumberPerSecond.Select(i => i)

lowNums.Throttle(TimeSpan.FromMilliseconds(100))

This produces a stream which will produce a value whenever lowNums stops producing a value for 100msecs. But since lowNums produces a value every 10 msecs, there won't be a time when nothing happens for 100msecs.

Upvotes: 2

Related Questions