bugGNU Octave - Bugs: bug #47455, very slow legend execution

 
 

bug #47455: very slow legend execution

Submitted by:  marco atzeri <matzeri>
Submitted on:  Fri 18 Mar 2016 11:12:02 AM UTC  
 
Category:  Plotting Severity:  3 - Normal
Priority:  3 - Low Item Group:  Performance
Status:  Confirmed Assigned to:  None
Originator Name:  Open/Closed:  Open
Release:  dev Operating System:  Any

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Tue 19 Nov 2019 06:40:30 PM UTC, comment #5: 

The changing of legend properties, particularly with set(), is now much faster.  It is the code that uses subplots that is particularly slow.  I extracted a benchmark test where I turn on profiling.

profile clear
clf;
x = (1:5)';
subplot (2,2,1);
plot (x, rand (numel (x)));
profile resume
legend (cellstr (num2str (x)), "location", "northwestoutside");
profile off
subplot (2,2,2);
plot (x, rand (numel (x)));
profile resume
legend (cellstr (num2str (x)), "location", "northeastoutside");
profile off
subplot (2,2,3);
plot (x, rand (numel (x)));
profile resume
legend (cellstr (num2str (x)), "location", "southwestoutside");
profile off
subplot (2,2,4);
plot (x, rand (numel (x)));
profile resume
legend (cellstr (num2str (x)), "location", "southeastoutside");
profile off

Using profexplore, it is clear that only two functions (update_layout_cb and axes) are responsible for most of the time consumed.

Top
  legend: 4 calls, 0.545 total, 0.006 self
    1) legend>update_layout_cb: 4 calls, 0.354 total, 0.004 self
    2) axes: 4 calls, 0.118 total, 0.001 self
    3) __go_text__: 4 calls, 0.021 total, 0.021 self
    4) legend>add_safe_listener: 28 calls, 0.014 total, 0.002 self
    5) legend>parse_opts: 4 calls, 0.010 total, 0.003 self
    6) legend>addproperties: 4 calls, 0.009 total, 0.002 self
    7) legend>update_numchild_cb: 4 calls, 0.003 total, 0.001 self
    8) setappdata: 8 calls, 0.003 total, 0.002 self
    9) addlistener: 64 calls, 0.002 total, 0.002 self
    10) ancestor: 4 calls, 0.001 total, 0.001 self

Within update_layout_cb, it is the function textitem_objects and set() that take the most time.  It might be possible to coalesce the set() calls in to fewer invocations (< 56 currently) which might help.

  legend: 4 calls, 0.545 total, 0.006 self
    legend>update_layout_cb: 4 calls, 0.354 total, 0.004 self
      1) legend>textitem_objects: 4 calls, 0.177 total, 0.019 self
      2) set: 56 calls, 0.121 total, 0.087 self
      3) legend>update_legend_position: 4 calls, 0.033 total, 0.003 self
      4) legend>textitem_data: 4 calls, 0.013 total, 0.004 self
      5) setappdata: 8 calls, 0.002 total, 0.001 self

Within textitem_objects, I see

      legend>textitem_objects: 4 calls, 0.177 total, 0.019 self
        1) __go_line__: 40 calls, 0.070 total, 0.070 self
        2) linkprop: 40 calls, 0.038 total, 0.026 self
        3) __go_text__: 20 calls, 0.030 total, 0.030 self
        4) setappdata: 40 calls, 0.009 total, 0.006 self
        5) get: 76 calls, 0.004 total, 0.004 self
        6) legend>update_marker_cb: 20 calls, 0.001 total, 0.001 self

There are 10 calls to _go_line_ per invocation even though there are only 5 legend objects.  Maybe we don't need to place a marker object if there is no marker to begin with?

(file #47902)

Rik <rik5>
Project Administrator
Mon 18 Nov 2019 08:09:15 PM UTC, comment #4: 

I pushed a new version of legend.m, which will only affect OpenGL toolkits. I attached a function which I used to try to devise a performance test of the old versus new legend code.
For single axes, the timings are generally better with the new code:

  • Adding legend item one after the other is now clearly faster (using ";displayname;" plot syntax)
  • Changing legend properties after creation is also faster

Now with subplots, which was already very slow with the old code, performance is poorer with the new code by 20%. For this we might need to implement an external layout manager.

file #47884)

Pantxo Diribarne <pantxo>
Project Member
Thu 17 Nov 2016 10:36:30 AM UTC, comment #3: 

This bug is still present in the current dev 4.3.0 (39f39eb4e476).

I filed task #14243 about rewriting legend.m

Pantxo Diribarne <pantxo>
Project Member
Wed 23 Mar 2016 09:09:37 PM UTC, comment #2: 

fltk and gnuplot are in the same ball park.

marco atzeri <matzeri>
Wed 23 Mar 2016 08:40:51 PM UTC, comment #1: 

What graphics toolkit was used for benchmarking?

Rik <rik5>
Project Administrator
Fri 18 Mar 2016 11:12:02 AM UTC, original submission:  

Legend execution time is very long when
first or new location is requested .
The legend time can be more than the plot time:

octave:3> source legenda_profile.m
bAfter =  1
Elapsed time is 0.405601 seconds.
Graph plotted
Elapsed time is 0.546001 seconds.
Legend command #1
Elapsed time is 0 seconds.
Legend command #2
Elapsed time is 0.501201 seconds.
Legend command #3
Elapsed time is 0.0468001 seconds.
remaining plot stuff
   #             Function Attr     Time (s)   Time (%)        Calls
-------------------------------------------------------------------
  72             _line_             0.265      48.57           23
  35                  set             0.078      14.29           83
   1               legend             0.031       5.71            1
  15                  get             0.031       5.71          375
  76              cellfun             0.031       5.71           23
  61                 text             0.016       2.86           17
   9                numel             0.016       2.86          382
  14                  gcf             0.016       2.86           41
  51          _go_axes_             0.016       2.86            1
  65          _go_text_             0.016       2.86           17
  77          _go_line_             0.016       2.86           23
  81              findobj             0.016       2.86            1
   2               nargin             0.000       0.00          194
   3             binary >             0.000       0.00          350
   4             ishandle             0.000       0.00           44
   5             prefix !             0.000       0.00          199
   6 _plt_get_axis_arg_             0.000       0.00           41
   7              strcmpi             0.000       0.00          166
   8                 find             0.000       0.00          105
  10            binary ==             0.000       0.00          378

marco atzeri <matzeri>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #47902:  bm_leg25.m added by rik5 (578B - text/x-matlab)
file #47883:  timings.png added by pantxo (80KiB - image/png)
file #47884:  legend_perf.m added by pantxo (6KiB - text/x-objcsrc)
file #36685:  legenda_profile.m added by matzeri (1KiB - application/octet-stream - Test case)

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

     

     

    Follow 9 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-11-19 rik5 Attached File- => Added bm_leg25.m, #47902
    2019-11-18 mtmiller Carbon-CopyRemoved 80942 => -
    2019-11-18 pantxo Attached File- => Added timings.png, #47883
        Attached File- => Added legend_perf.m, #47884
    2017-02-08 johasixt Carbon-Copy- => Added johasixt
    2016-03-22 mtmiller Priority5 - Normal => 3 - Low
        StatusNone => Confirmed
        Release4.0.0 => dev
    2016-03-18 matzeri Attached File- => Added legenda_profile.m, #36685

    Back to the top


    Powered by Savane 3.5