Group Performance Issue

697
4
02-07-2020 10:04 AM
AdamDavis
Occasional Contributor

The more levels of group an element is put in the slower it is.

100 lines at root level 3 seconds

100 lines at Level1 14 seconds

100 lines at Level2 19 seconds

It looks like Pro makes the Element at root level and then moves it which means there's a performance hit!

Is there a way of speeding this up?

Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            Layout layout = Project.Current.GetItems<LayoutProjectItem>().FirstOrDefault()?.GetLayout();
            GroupElement groupElement = LayoutElementFactory.Instance.CreateGroupElement(layout);
            CIMElement cimGroupElement = groupElement.GetDefinition();
            cimGroupElement.Name = "First Level Group";
            groupElement.SetDefinition(cimGroupElement);
            GroupElement groupElement2 = LayoutElementFactory.Instance.CreateGroupElement(groupElement);

            for (int i = 0; i < 100; i++)
            {
                List<Coordinate2D> lineCoordinates = new List<Coordinate2D> { new Coordinate2D { X = i, Y = 0 }, new Coordinate2D { X = i, Y = 100 } };
                Polyline polylineTic = PolylineBuilder.CreatePolyline(lineCoordinates);
                CIMLineSymbol lineSym = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlackRGB, 1.0, SimpleLineStyle.Solid);
                GraphicElement lineElm = LayoutElementFactory.Instance.CreateLineGraphicElement(groupElement2, polylineTic, lineSym);
                CIMElement cimElement = lineElm.GetDefinition();
                cimElement.Name = "Line" + i;
                lineElm.SetDefinition(cimElement);
            }
            stopwatch.Stop();
            Debug.Print((stopwatch.ElapsedMilliseconds / 1000).ToString());

Adam

0 Kudos
4 Replies
JeffBarrette
Esri Regular Contributor

Adam,

Thank you for reporting this.  I can see this with 2.4 and 2.5.  We will investigate and hopefully address it for 2.6.

Jeff - Layout team

0 Kudos
AdamDavis
Occasional Contributor

Hi Jeff,

I do think the addition of elements needs changing.

The current way seems to be create the element and then change the properties.

Even if the element is added to a group then the element is created at the root level and then moved. It can be seen doing that in the Pro TOC. When making a lot of these in multiple layout Pro has to do a lot of individual TOC/UI updating which makes Pro become unresponsive for a long time.

So, it would be good if the SDK team could look both at

1) Improving the efficiency of creating elements (putting elements directly into the correct group and adding the name property to the Factory creation functions) 

2) Being able to suspend Pro Window update; do a bunch of stuff and then turn it back on and refresh current layout.

In the long term it would be ideal if we could access and modify project files (aprx) without having them open in Pro (like we can with mxds in in Desktop).

Adam

0 Kudos
JeffBarrette
Esri Regular Contributor

This has been addressed at 2.7. 

A number of performance improvements have been made that allow the code below to run in about 1 second vs about 24 seconds in Pro 2.6.  The biggest improvement  is the fact that we've added bulk element creation tools.  Here is the modified code that will run much faster in Pro 2.7

Stopwatch stopwatch = new Stopwatch();
      await QueuedTask.Run(() =>
      {
      
      stopwatch.Start();
      Layout layout = Project.Current.GetItems<LayoutProjectItem>().FirstOrDefault()?.GetLayout();
      GroupElement groupElement1 = LayoutElementFactory.Instance.CreateGroupElement(layout);
      CIMElement cimGroupElement = groupElement1.GetDefinition();
      cimGroupElement.Name = "First Level Group";
      groupElement1.SetDefinition(cimGroupElement);
      GroupElement groupElement2 = LayoutElementFactory.Instance.CreateGroupElement(groupElement1);
      GroupElement groupElement3 = LayoutElementFactory.Instance.CreateGroupElement(groupElement2);

      var graphics = new List<CIMGraphic>();  //new at 2.7
      var names = new List<string>();         //new at 2.7
      for (int i = 0; i < 100; i++)
      {
        List<Coordinate2D> lineCoordinates = new List<Coordinate2D> { new Coordinate2D { X = i, Y = 0 }, new Coordinate2D { X = i, Y = 100 } };
        Polyline polylineTic = PolylineBuilder.CreatePolyline(lineCoordinates);
        CIMLineSymbol lineSym = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlackRGB, 1.0, SimpleLineStyle.Solid);
        graphics.Add(new CIMLineGraphic() { Line = polylineTic, Symbol = new CIMSymbolReference() { Symbol = lineSym } });
        names.Add("Line" + i);              //new at 2.7
      }
      LayoutElementFactory.Instance.CreateGraphicElements(groupElement3, graphics.ToArray(), names.ToArray());  //new at 2.7
      stopwatch.Stop();
      System.Windows.MessageBox.Show((stopwatch.ElapsedMilliseconds / 1000).ToString());
      });

Jeff - arcpy.mp / Layout SDK teams

0 Kudos
AdamDavis
Occasional Contributor

Hi Jeff,

That's brilliant news. Would be great to test it out in Alpha/Beta if possible.

Adam

0 Kudos