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

 
 

bug #47455: very slow legend execution

Submitter:  marco atzeri <matzeri>
Submitted:  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
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

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>
Group 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>
Group 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>
Group 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>
Group 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)
  •  

    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 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.13-f8d8.
    Corresponding source code