bugGNU Octave - Bugs: bug #55707, graphics backend takes long when...


bug #55707: graphics backend takes long when plotting many lines

Submitter:  Hartmut <hardy>
Submitted:  Wed 13 Feb 2019 11:21:18 AM UTC
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Performance
Status:  Confirmed Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup

Jump to the original submission

Fri 15 Feb 2019 04:37:33 PM UTC, comment #13: 

@Hartmut: I agree that equal times across all is a general clue that the slow down lies not in the rendering, but somewhere else.  But until we have some profiling data, I don't know where "somewhere else" is.

Rik <rik5>
Group administrator
Fri 15 Feb 2019 09:01:43 AM UTC, comment #12: 

I just want to point your attention to some detail of my original bug report (mostly in response to Rik's comment #6 ):

  • The "slowness" is precisely the same for all THREE graphics backends, not only qt, also fltk and even the gnuplots backend is precisely as slow.

I have no clue at all of the implementation of Octave's graphics code. But doesn't the above fact suggest that the observed speed bottleneck is somewhere in a piece of code, that is common for all three backends? So I think this rules out the OpenGL code parts for example (because I assume they won't be used with graphics_toolkit gnuplot, would they?)

Hartmut <hardy>
Thu 14 Feb 2019 08:14:25 PM UTC, comment #11: 

Sorry! My previous comment is related to bug #55622.

Thu 14 Feb 2019 07:49:28 PM UTC, comment #10: 

It seems that MATLAB has used the concept of nullable type.

From the documentation:

"An empty array in MATLAB is an array with at least one dimension length equal to zero. Empty arrays are useful for representing the concept of "nothing" programmatically."

All nonabstract MATLAB classes have a method named empty. For example we can write:

A = int16.empty(5,0);

It means that all non abstract types all nullable. Therefore we can make array of nulls and iterate over nulls.
--Interesting discussion--

Thu 14 Feb 2019 04:36:08 PM UTC, comment #9: 

Overall performance in Octave has been declining over several versions.  JWE's recent change to the way the symbol table works has been the first improvement in performance in ages.

Rather than guessing at the root cause, I would like to get some data on where the slow parts of the code are.  This means running Octave under a profiler.  I tried it several years ago and had a hard time, but I guess it can't be put off any more.

Rik <rik5>
Group administrator
Thu 14 Feb 2019 03:49:07 PM UTC, comment #8: 

@Markus, Rik: At least, Lachlan stated in bug #47052, that when creating line objects most of the time was spent initializing graphics_objects. A way to see that line objects rendering is quite fast is to try to use the "pan" tool on the figure:

tic; plot (1:1000, 10); toc ## -> 28s on my system

Panning is fast: I can't see jagged rendering which means that it doesn't take more than a few 10ms for each redraw.

On the contrary the example from bug #40663 is slow the first time (when creating patch objects) but also when panning

a = randn(1000,3);

Pantxo Diribarne <pantxo>
Group Member
Thu 14 Feb 2019 07:43:35 AM UTC, comment #7: 

This is just a feeling and I can't put any hard numbers on it. But I suspect that it isn't necessarily in the gl-render code but in the cascade of update functions in our graphics code that slows down the execution. It feels like we could do a better job in reducing the operations to the bare minimum - especially when creating a new graphics object. But each time I try to understand what is actually going on, I get lost in the torrent of callbacks that are triggered.

Markus Mützel <mmuetzel>
Group administrator
Wed 13 Feb 2019 05:28:01 PM UTC, comment #6: 

I was the one who checked in a partial fix for bug #47052.  That produced a 35% speed-up and the changes were only to m-files. 

You could benchmark it, or use the profiler, but my bet is that the problem now is in the call to _go_line_ which is from the m-file in to the C++ and further on in to the OpenGL renderer.

There is a similar report about scatter being slow and in that case it was definitively tracked down to the call to _go_patch_.

In summary, I think we need an OpenGL expert to give our code a review.  Plotting 1,000 points should be very, very fast.

This is definitely a task for the development branch.

Rik <rik5>
Group administrator
Wed 13 Feb 2019 02:24:39 PM UTC, comment #5: 

The other bug about slow plotting was probably bug #47052 which was closed in the meantime.
We could probably use this bug report for tracking down in the C++ code why Octave takes so long when plotting many lines.
Probably better suited for the default branch.

Markus Mützel <mmuetzel>
Group administrator
Wed 13 Feb 2019 02:20:40 PM UTC, comment #4: 

@Pantxo: The results for your test code in Matlab:

>> x = 1:1000; % vector
y = 10;     % scalar
hlines = plot (x, y);
sprintf ('x,y-> %d line(s), marker ''%s''', numel (hlines), get (hlines(1), 'Marker'))

ans =

x,y-> 1000 line(s), marker 'none'

Markus Mützel <mmuetzel>
Group administrator
Wed 13 Feb 2019 01:57:03 PM UTC, comment #3: 

@Marku: Oups, I hadn't seen your answer.

Pantxo Diribarne <pantxo>
Group Member
Wed 13 Feb 2019 01:56:26 PM UTC, comment #2: 

@Harmut: The expected behavior is properly documented in Matlab:

>> If one of X or Y is a scalar and the other is either a scalar or a vector, then the plot function plots discrete points. However, to see the points you must specify a marker symbol, for example, plot(X,Y,'o').

Now the question is whether Matlab creates as much line objects as the length of the vector (this is what Octave currently does, but much more slowly than acceptable), or if it simply creates one line with marker "none" (the equivalent of "plot (x, y*size (x), 'Marker', 'none')").

What does the following do in Matlab:

x = 1:1000; % vector
y = 10;     % scalar
hlines = plot (x, y);
sprintf ('x,y-> %d line(s), marker ''%s''', numel (hlines), get (hlines(1), 'Marker'))

If there is only one line then we can easily speed up this call form. Otherwise, we must stay ML compatible and we end up having to fix the very slow graphics_objects creation (known bug but I can't find the number ATM).

Pantxo Diribarne <pantxo>
Group Member
Wed 13 Feb 2019 01:33:31 PM UTC, comment #1: 

(A) It looks like Matlab produces an empty plot because - unlike Octave - it doesn't add markers if there is only one point per line.

(B) I actually prefer Octave's behavior.

For similar results in Matlab use:

x = 1:1000; % vector
y = 10;     % scalar

plot(x, y, 'o');

(C) I think we shouldn't automagically transpose input vectors.

(D) Octave takes quite long when plotting many lines. I think there was a bug report about it a while ago. But I cannot find it right now.

Markus Mützel <mmuetzel>
Group administrator
Wed 13 Feb 2019 11:21:18 AM UTC, original submission:  

I just unintenionally noticed, that plotting a scalar value versus a vector takes incredibly long in Octave. Here is a small script to show what I mean:

close all

graphics_toolkit qt % fltk or gnuplot behave the very same

x = 1:1000; % vector
y = 10;     % scalar

plot(x, y);

First of all: I don't know if this usage of "plot(vector,scalar)" is documented at all. But it doesn't throw any errors, neither in Octave nor in Matlab.

Here are my timing results with the above script in Octave:

  • Linux + Octave 4.4.1 (qt, fltk or gnuplot) -> 7 sec
  • Linux + Octave 5.0.91 -> 7 sec
  • Win 10 + Octave 4.4.1 (qt) -> 43 sec
  • Win 10 + Octave 5.0.91 (qt, fltk or gnuplot) -> 50 sec

As a result Octave produces a plot window with 1000 differently colored little circles.

Here is the result of the above script in Matlab:

  • Win 10 + Matlab (probably V2017b or V2018b) -> 0.5 sec

Matlab produces a totally emtpy plot window as result.


In principle I like the current Octave behavior better than the Matlab one. This could be a nice "Octave only" feature. If someone (like me in this case) unintenionally plots only a single y value for a vector of x values it's quite obvious what should be plotted. And the resulting Octave plot is fine for this purpose.
But: It takes incredibly long until the final plot apprears in the window. I first did this under Windows 10, where it takes nearly a full minute! Meanwhile I had already Ctrl-C'ed the script and started searching of a bug somewhere. So in the current implementation, this "Octave only" feature is disturbing the user.

Possible solutions:

  • (A) We could make this call to plot "illegal" and throw a (fast) error message. (But Matlab doesn't).
  • (B) We could do the same as Matlab, and return an empty plot window.
  • (C) We could speed up our Octave plotting code for this special case by just plotting a line. It assume this should be doable without too much coding, because just using the following code is already fast enough: "plot(x, y.*ones(size(x)))". This substitution code produces a line instead a series of circles, which is (a) much faster, (b) kind of Matlab compatible and (c) as helpful as the previous graphics output in my use case. But this might spoil the graphical output for users who actually do want this serious of cirles output. (What comes back to the question: Is the current Octave behavior documented for this case? Do we want to stay backwards compatible if not?)
  • (D) We could speed up our Octave plotting code and still generate a row of circles. I am not sure how much work this would be, but I assume much more.

Hartmut <hardy>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by pantxo (Posted a comment)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by hardy (Submitted the item)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.


    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-02-13 mmuetzel StatusNone Confirmed
        Release5.0.91 dev
        Summaryplot(vector, scalar) is very slow graphics backend takes long when plotting many lines

    Back to the top

    Powered by Savane 3.13-b921.
    Corresponding source code