[GIS] arcpy.mapping.ListLayoutElements() takes longer in tool than in ArcMap

arcgis-10.0arcpyperformance

Has anyone else noticed that accessing elements from arcpy.mapping.ListLayoutElements() through a tool script takes longer than within ArcMap? Whether using a specific name, wildcard or nothing, the call takes on the order of 90 seconds or longer to return:

arcpy.AddMessage("  Start: " + str(datetime.now()))
mapDoc = arcpy.mapping.MapDocument(mapDocumentPath)
elements = arcpy.mapping.ListLayoutElements(mapDoc, "GRAPHIC_ELEMENT")
arcpy.AddMessage("  Finished: " + str(datetime.now()))

Start: 2011-05-24 12:29:28.479000
Finished: 2011-05-24 12:31:10.510000

When the call is made within ArcMap the return is instantaneous.

mapDoc = arcpy.mapping.MapDocument("CURRENT")
elements = arcpy.mapping.ListLayoutElements(mapDoc, "GRAPHIC_ELEMENT")

In both instances, I'm referencing the same map document.

Using ArcGIS 10 SP2.

  1. It may not be obvious but the results are instantaneous when the script is run against "CURRENT". Specify any map document other than "CURRENT" and the script will slow down.
  2. I executed a loop as Jason suggested and found little difference between the first call to ListLayoutElements() and the last. The first selection took 28 seconds while the other nine averaged 24 seconds.
  3. The map document has nine data frames and nine corresponding legend elements that were converted to graphics. When these "legends" are present in the document then ListLayoutElements() is slow; when they're deleted then ListLayoutElements() returns immediately.

Best Answer

There were issues with this at 10.0, but we've ironed out all the visible ones in the service packs. You should be seeing a significant improvement in performance on ListLayoutElements and friends using SP2 over SP1 or 10.0. Are subsequent calls to the same function as slow? What if you add the time that it takes to load the document into ArcMap into account? Would that bring the two to something close to one another?

Try this:

arcpy.AddMessage("  Start: " + str(datetime.now()))
mapDoc = arcpy.mapping.MapDocument(mapDocumentPath)
for counter in xrange(10):
  elements = arcpy.mapping.ListLayoutElements(mapDoc, "GRAPHIC_ELEMENT")
  arcpy.AddMessage("  Finished %i: %s" % (counter + 1, str(datetime.now())))

Outside of ArcMap, the Map Document classes need to set up what is essentially a hardware context to draw to to ensure the metrics of layout elements are correct. This is not necessary in the active ArcMap document because it has the hardware context of the application's window, but it may account to some extent for the speed differences.