matplotlib webagg benchmarks

As promised in last week's Google Hangout to the IPython developers meeting -- I have some concrete timings and numbers on the matplotlib WebAgg backend in a couple of different scenarios.

First, let me apologize -- the way I was timing binary websockets vs. text websockets previously was wrong. The actual impact of it is much smaller than I had originally estimated -- so the discussion about whether to include binary websockets in IPython may have been all for naught.

For benchmarking, I used two different plots. One is the classic "simple_plot.py" sine wave, which tests sort of the "easy case" where very little of the image is updated in each frame, and the other was "animation/dynamic_image.py" in which most of the plot is updated in each frame.

I tested both scenarios with client and server on my local machine, and through an ssh tunnel that goes over wifi, the public university network, to my home's 15/5 MBps cable connection 28 miles away and back.

For (A), the average frame weighs in at around 20kb. For (B), it's around 90kb. For base64, multiply by those numbers by 4 / 3.

On my local machine, I can push through about 18 fps, so a bandwidth of 2.8MBps (were it sustained, which it rarely is). On the tunnel, I fluctuate between 7 and 10 fps, which is quite usable, and quite near the practical upper limit on the bandwidth of that connection.

However, the problematic thing for the remote connection is the latency. Locally, I average a fairly steady 250ms to roundtrip from a mouse event to an updated frame. Remotely, it fluctuates randomly between 400ms (still usable) and 3000ms. Some more careful dynamic scaling of events can probably make that easier to use, perhaps. I know games often use UDP and handle robustness to packet loss in a different way as a way to remove some of the latency of TCP. I have no idea if such a thing would be possible over a web socket, of course.

I could not measure any statistically significant change in framerate or latency between a binary websocket and a non-binary one. However, there is a 10% increase in CPU time on both the python side and the browser. It so happens that I wasn't saturating my CPU, so it had no net impact. Likewise, I am not saturating my bandwidth, so the additional size doesn't matter in this case. But I suspect if either one of those resources is starved, the additional 10% cpu time and 25% bandwidth increase may matter.

Mike

As promised in last week's Google Hangout to the IPython developers
meeting -- I have some concrete timings and numbers on the matplotlib
WebAgg backend in a couple of different scenarios.

First, let me apologize -- the way I was timing binary websockets vs.
text websockets previously was wrong. The actual impact of it is much
smaller than I had originally estimated -- so the discussion about
whether to include binary websockets in IPython may have been all for
naught.

Part of our message spec includes binary blobs trailing after the JSONable
message dicts.
Currently this is used by `data_pub` and `apply` messages, but it could
theoretically be extended to display data for streaming output, such as
video or audio. Right now, we have no way of propagating that part of the
message spec up to notebook frontends, because we do not yet have any
binary messages that the notebook frontend can understand. In these cases,
a switch to binary websocket may still make sense, even without a
performance argument.

For benchmarking, I used two different plots. One is the classic
"simple_plot.py" sine wave, which tests sort of the "easy case" where
very little of the image is updated in each frame, and the other was
"animation/dynamic_image.py" in which most of the plot is updated in
each frame.

I tested both scenarios with client and server on my local machine, and
through an ssh tunnel that goes over wifi, the public university
network, to my home's 15/5 MBps cable connection 28 miles away and back.

For (A), the average frame weighs in at around 20kb. For (B), it's
around 90kb. For base64, multiply by those numbers by 4 / 3.

On my local machine, I can push through about 18 fps, so a bandwidth of
2.8MBps (were it sustained, which it rarely is). On the tunnel, I
fluctuate between 7 and 10 fps, which is quite usable, and quite near
the practical upper limit on the bandwidth of that connection.

However, the problematic thing for the remote connection is the
latency. Locally, I average a fairly steady 250ms to roundtrip from a
mouse event to an updated frame. Remotely, it fluctuates randomly
between 400ms (still usable) and 3000ms. Some more careful dynamic
scaling of events can probably make that easier to use, perhaps. I know
games often use UDP and handle robustness to packet loss in a different
way as a way to remove some of the latency of TCP. I have no idea if
such a thing would be possible over a web socket, of course.

I could not measure any statistically significant change in framerate or
latency between a binary websocket and a non-binary one. However, there
is a 10% increase in CPU time on both the python side and the browser.
It so happens that I wasn't saturating my CPU, so it had no net impact.
Likewise, I am not saturating my bandwidth, so the additional size
doesn't matter in this case. But I suspect if either one of those
resources is starved, the additional 10% cpu time and 25% bandwidth
increase may matter.

Thanks for these numbers - I suspect the potential penalty for an extra hop
between the kernel and the notebook will not be significant in any case
where the kernel is local to the server and the client is remote.

-MinRK

ยทยทยท

On Tue, Jul 30, 2013 at 2:28 PM, Michael Droettboom <mdroe@...31...> wrote:

Mike
_______________________________________________
IPython-dev mailing list
IPython-dev@...336...
http://mail.scipy.org/mailman/listinfo/ipython-dev

Hi Mike,

thanks a lot for providing these numbers...

I think for now, the plan we hatched at the dev meeting continues to
look reasonable (integrate interactive webagg support into the
%matplotlib magic so it would be seamless to users on localhost or
very open networks). But the fact that the overhead is lower than
we'd thought lends weight to the idea of giving mpl an easier way to
integrate this functionality into our existing design before we cross
the binary ws bridge...

One way or another, exciting times!

Cheers,

f