piaoyongren / core-plot

Automatically exported from code.google.com/p/core-plot
0 stars 0 forks source link

Plotting O(1e6) points is slow #114

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
CPScatterPlot with >1e6 points takes noticeable time to display.

There are many possible avenues for performance optimization which I will 
consider:

1. Better caching in CPPlot may allow subclasses to cache pre-calculated plot 
information
2. Providing data in POD numeric form (i.e. double[] or an NSData* of doubles) 
may alleviate 
NSNumber/NSDecimal->CGFloat conversion. The bwnumericdata branch provides a 
nice start on 
this method.
3. CGPath may be very slow for this size data, and we might want to consider 
faster alternatives 
(if they exist)
4. Since large datasets cannot be displayed on fixed resolution output, 
filtering to subsample the 
output may be useful (see #103)

Profiling is obviously the first step in prioritizing these approaches.

Original issue reported on code.google.com by barryw...@gmail.com on 30 Mar 2010 at 6:53

GoogleCodeExporter commented 9 years ago
Fully agree with this. And profiling certainly is the most important step here.

A few tidbits that come to mind:

- Would be difficult to get rid of CGPath. I suppose you could replace it with 
just single lines, but you lose the 
ability to do nice dashes. Guess you could toggle based on whether dashes are 
needed.
- I think caching data in a buffer of doubles or NSDecimals could certainly 
help, but I wonder if that is 
actually the true bottleneck. Brad Larson suggested it was a significant 
bottleneck
- One place where performance is a real issue is when you scroll. A possible 
solution for this particular issue 
would be to have CPPlot draw into a CGImage as  a cache, and to use that image 
to render the scrolled layer, 
only redrawing the new parts. The image could even be a bit bigger than the 
viewable area, to prevent 
redraws.

Original comment by drewmcco...@mac.com on 30 Mar 2010 at 7:11

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Good thoughts. I'll report back with profiling numbers and we can consider the 
plan from there.

Original comment by barryw...@gmail.com on 30 Mar 2010 at 7:27

GoogleCodeExporter commented 9 years ago
The last time I profiled the drawing using Shark and Instruments, the limiting 
factor were the Core Graphics 
drawing routines.  As far as I could tell, it wasn't the behind-the-scenes math 
so much as it was the actual 
drawing.  This is particularly noticeable when the plots are scrolled around, 
even with smaller numbers of data 
points.

If we could somehow integrate CATiledLayer for rendering large plots once, then 
CAScrollLayer for scrolling 
around, we might be able to dramatically improve scrolling and zooming 
performance.

Original comment by waupacalarson@gmail.com on 14 Apr 2010 at 7:54

GoogleCodeExporter commented 9 years ago
I don't know if you really need the scroll layer. I think we can still handle 
the scrolling ourselves, but perhaps use 
a tiled layer for drawing in certain classes, such as plot classes.

But maybe it is just cleaner to introduce out own image caching in CPLayer. I 
did something like this in the 
narrative framework, and I don't think it was that difficult. Just have a flag 
that allows you to cache drawing in an 
offscreen image, and perhaps leave a bit of space at the sides. Either that, or 
our own tiled image caching. 
Probably not as difficult as it sounds.

Original comment by drewmcco...@mac.com on 14 Apr 2010 at 8:10

GoogleCodeExporter commented 9 years ago
I don't think that solution could help zooming performance as graph needs to be 
redrawn, axis label to rescale and other things.

I agree that it could really help with scroll.
However core plot is slow to begin with and never real time. I have done some 
empirical research.
Drawing only the background and 2 axis is already slow when scrolling, I don't 
know 
why. The actual plot is not so demanding compared to that.
Also what really kill performance is the grid.

Another test I did was drawing a small version of the graph. Actually smaller 
the 
graph faster the draw. Not so obvious, point should be the same to draw, only 
take a 
lesser portion of the screen. However even smaller graph aren't real time when 
scrolling.

Original comment by m.colo...@executive.it on 23 Apr 2010 at 1:07

GoogleCodeExporter commented 9 years ago
Much of the performance bottleneck is simply the drawing. That's why a smaller 
graph is faster: less 
compositing.

Core Plot can certainly be real time on a Mac. On iPhone, it is much slower, 
and you would struggle to get real 
time plotting. That is simply because the iPhone composites the layers much 
slower, and Core Plot has many 
transparent layers in each graph. Short of moving away from core animation, 
which we don't want to do, there is 
probably not too much to be done about this. Just wait for faster hardware. 
(Interesting to see how it goes on the 
iPad.)

Original comment by drewmcco...@mac.com on 23 Apr 2010 at 1:32

GoogleCodeExporter commented 9 years ago
What I meant is that probably is core animation that it's not optimized at all. 
What 
can make it so much slower to draw the same exact graph but in less space? To 
draw a 
line should be the same, maybe gradient or similar.

I wonder what kind of library did other apps use to draw graph. At least the 
one I 
saw was really fast. I guess that's not core animation.

Saying that it won't probably get fasters make multi touch and even scroll 
useless 
on iphone. Maybe on ipad.

Drawing in a CGImage as was suggested, do you think it is how Bloomberg managed 
to 
get a so fast graph? (counting the fact that it has less to draw without the 
refined 
graphic)

Alternatively what can actually be cut to improve performance? Like a light 
version.
I still don't get how come that scroll is slow even when drawing only the 
background 
and the axis.

Original comment by m.colo...@executive.it on 23 Apr 2010 at 2:22

GoogleCodeExporter commented 9 years ago
Yes, you can certainly get much faster if you drop core animation, but at the 
cost of flexibility. In future, we are 
going to add animation and other nice stuff. You can already do some of this. 
Direct quartz 2D will certainly be 
faster, and if that is what you need, you should consider going with another 
library.

Even with no plots, a CPGraph has many layers, probably something like 10 in 
all. And the layers are big, most 
covering the whole drawing area. This does mean that core graphics has to do a 
lot more compositing of data. If 
you are just drawing into one layer with quartz, you end up doing much, much 
less.

Original comment by drewmcco...@mac.com on 23 Apr 2010 at 3:31

GoogleCodeExporter commented 9 years ago
Something that may be interesting to test is to see whether drawing the graph 
into a bit map image like a PNG, 
using the methods already provided in CPLayer, and then displaying that PNG in 
a separate UIView, is any faster. 
It may well be, because you are effectively collapsing all the layers into one. 
If this was effective, it may be 
possible to somehow offer a fast mode, where the CPGraph is effectively 
rendered into a single layer, and that is 
what is displayed. 

But maybe it makes no difference.

Original comment by drewmcco...@mac.com on 23 Apr 2010 at 3:37

GoogleCodeExporter commented 9 years ago
In the case where you want to scroll the graph quickly and the data isn't 
changing very often, we might be able 
to render the plots, grid lines, and other parts that scroll into a single 
image and set that as the background of a 
single scrolling layer. Maybe combine this idea with a previous suggestion to 
use a CATiledLayer.

Original comment by eskr...@mac.com on 23 Apr 2010 at 7:16

GoogleCodeExporter commented 9 years ago
I think that drawing the graph in an image could help. Still don't know if it 
could 
work even on zoom without loss of detail (is there a way to create vectorial 
image?) 
but by watching I starting to think that Bloomberg did it that way. Other 
things 
that could help would be light version of the object to draw (eg. nothing with 
gradient, everything computed with the minor effort, ect.), caching of layers 
or 
elements that didn't change and maybe the ability to selective disable each 
layer 
(you may want to be able to draw only the plot at a certain point). With these 
maybe 
core plot could be a viable option even on iphone, would be a pity otherwise.

However I have to say that I'm a bit disappointed by Core Animation performance 
on 
iPhone and iPod, it is said that it has good performance and is used to do 
animation on them, still it hangs even in scrolling or zooming.

Original comment by m.colo...@executive.it on 25 Apr 2010 at 7:22

GoogleCodeExporter commented 9 years ago
I read something about core animation performance. One thing that is said is 
that 
not opaque (blended) layer really impact performance. So setting layer opaque 
when 
possibile could reduce the load. Is there something that can be done in this 
direction that could help core plot performance?

Original comment by m.colo...@executive.it on 26 Apr 2010 at 7:57

GoogleCodeExporter commented 9 years ago
No, not much. Like I said, you could draw into fewer layers, maybe even one. 
This could be done reasonably 
simply, because CPLayer is already setup to allow drawing into any context. 

To actually keep all layers on screen, and make them opaque, would not really 
be possible. You can imagine a 
layer with a single axis being drawn with an opaque background. It would just 
cover up the rest of the graph.

At this point, your best option would be to try drawing into an image at screen 
resolution, and displaying the 
image. That should come close to layer-less drawing.

Original comment by drewmcco...@mac.com on 26 Apr 2010 at 8:08

GoogleCodeExporter commented 9 years ago
Actually, come to think of it, you don't even need to draw into an image. Just 
setup a UIView, and in the 
drawRect: method, render the CPGraph directly into the context. I would be very 
interested to hear if this helps 
performance. If it does, it might be a good to adapt the host view class so 
that it can do this type of drawing.

Original comment by drewmcco...@mac.com on 26 Apr 2010 at 8:10

GoogleCodeExporter commented 9 years ago
I actually tested it and I can tell that there is no performance improvement by 
rendering into an image. I am not 
sure how easy would it be to render it all on a single layer or two in single 
steps. Consider one layer for the 
background and grid lines, another for the plots and a third (well that's 
already three) for the grid lines. If the 
plots do not overlap the gridlines they they may be placed on the background 
layer. Again, I have no idea 
whether this is difficult to achieve. 

Original comment by carbon...@gmail.com on 23 May 2010 at 5:32

GoogleCodeExporter commented 9 years ago
Has there been any further developments on this issue of late? I seem to be 
running into the same problem where, on the iPhone panning a medium sized graph 
left and right results in a considerable lag behind the users finger (but the 
simulator is actually very accurate, which is frustrating)

Original comment by mark.mac...@gmail.com on 12 Aug 2010 at 5:07

GoogleCodeExporter commented 9 years ago
The only thing i do is insert the CPGraphHostingView into a scroll view, and 
adjust the frame of the hosting view, and the contentSize of the scrollView, 
and this solve the problem.

Original comment by exequiel...@gmail.com on 12 Nov 2010 at 3:08

GoogleCodeExporter commented 9 years ago
hello all ,

I am facing a problem while running the application. I have 307 Error messages 
which commonly shows "error: CorePlot-CocoaTouch.h: No such file or directory 
".. I am not able to figure it out the reason for this. I have properly 
included the lib for the Cocoa Touch and also do have the cocoa-touch project 
file in my bundle. Have added the framework. Tried many options but could not 
solve it out. If you can help me out of it will be very great. I am also 
attaching a screen Shot of my app for yours reference. 

Thanks and Regards  

"

Original comment by iPhoneDe...@gmail.com on 1 Dec 2010 at 1:30

Attachments:

GoogleCodeExporter commented 9 years ago
Best to ask this on our mailing list.
You probably need to set the header search path in the build settings. See an 
example app, or our wiki:

http://code.google.com/p/core-plot/wiki/UsingCorePlotInApplications

Original comment by drewmcco...@mac.com on 1 Dec 2010 at 3:42

GoogleCodeExporter commented 9 years ago
Performance issues have been addressed as much as possible. Some drawing is 
just intrinsically slow, and culling of data points is probably the best 
approach there.

Original comment by drewmcco...@mac.com on 8 Jan 2011 at 9:59