halfhp / androidplot

Charts and plots for Android
http://androidplot.com
Apache License 2.0
516 stars 160 forks source link

Weird correlation between graph size and performance #96

Open OuterObsessionSoftware opened 5 years ago

OuterObsessionSoftware commented 5 years ago

How I have things set up

Android plot version: 1.5.7

I've been using androidplot for real-time graphing a while now and really like the library. Recently I've been working on a project that evolves processing and rendering two images at 60fps with opencv, I then take the processed data from opencv and plot it at 60fps.

Because opencv is quite resource intensive my implementation of the plotting has to be very optimised, for this I've set my graph up the same as the ecg graph example but instead used FastXYSeries and FastLineAndPointRenderer.

My graph plots 5 seconds worth of data (horizontal size is 300 - update rate is 60hz thus 5 seconds to traverse whole graph) And the vertical is -300 to 300.

The issue

So the problem is if android-plot isn't optimised properly the two video feeds processing the opencv data can't maintain the 60fps they need it. With the graph in even with FastXYSeries, FastLineAndPointRenderer and a fixed graph size I wasn't reaching 60fps so I started trying some random things.

One of the things I tried by chance was decreasing the size of the plot in my layout file, I didn't expect it to cause any change at all. To my surprise when I shrank the graph the framerate jumped. So I made it a little more smaller and before I knew it I had doubled the framerate of my processed images!

At first I thought the whole graph simply wasn't being rendered properly resulting in the increased framerate but looking closely the graph seems pretty spot on. My thoughts are this is either some obscure bug or unintended behavior?

To give you an idea this gives me about 20-30fps on my processed images: lag

And simply reducing the size as such will result in my fps doubling(60fps+): no-lag

For my layout I'm using androidx.constraintlayout, the reason you can see labels on graph in the preview is because I couldn't get the built in labels to format properly so I just used textview as labels instead (a little messy but works great)

How to replicate

I haven't had time to piece together an example project demonstrating the issue but my guess would be that if you took the ecg example and set the refresh rate to something crazy high and started doing some resource intensive task (plotting primes?) you would then see a difference in performance based on the size of the graph from xml layout.

If I get time I might throw something together.

halfhp commented 5 years ago

@OuterObsessionSoftware thanks for the report - I'll probably not have a chance to do any serious investigation until Friday, but one quick question - which render mode are you using? If you aren't using background rendering (which is not the default) that would go a long way to explaining this behavior.

OuterObsessionSoftware commented 5 years ago

In my xml I have app:renderMode="use_background_thread" which I assume means I'm using background mode.

OuterObsessionSoftware commented 5 years ago

Also this is probably unrelated but every maybe 4th time I launch my application I get a NPE from my redrawer.

D/com.androidplot.util.Redrawer: Redrawer thread exited.

E/AndroidRuntime: FATAL EXCEPTION: Androidplot Redrawer java.lang.NullPointerException: Attempt to invoke virtual method 'void com.androidplot.Plot.redraw()' on a null object reference at com.androidplot.util.Redrawer.run(Redrawer.java:113) at java.lang.Thread.run(Thread.java:762)

OuterObsessionSoftware commented 5 years ago

Answered my own question. Redrawer error was due to not calling redrawer.finish(); in onStop()