I'd like to quantitatively measure the display performance of mosaic datasets, image service layers, raster layers, feature layers, etc. in ArcMap 10.

How can I measure the draw time of a particular layer (or the complete drawing process if that is the only option) in ArcMap? What are the interfaces, objects and events involved? Is the StopWatch class in .NET suitable for accurately measuring this type of operation?

Has anyone already created an ArcMap add-in or extension for this purpose?


5 Answers 5


I'm not sure how accurate this is, but I've done this in the past:

Create a LayerExtension class that implements ILayerExtensionDraw. Within the class keep a list of timings. A Timing is a class with a start tick and an end tick property. When BeforeLayerDraw is called for esriDPGeography, instantiate a new timing intance and set the StartTick property to Environment.TickCount. When AfterLayerDraw is called for esriDPGeography set the EndTick to Environment.TickCount and add it to the list.

In looking at this answer, I'd say you're better off using StopWatch than TickCount.

Add the LayerExtension to the layer via ILayerExtensions.Add method. Do not keep a strong reference to the ILayer within the layerextension.

Write a button that lets you add and clear layerextensions from layers in the map.

Write a button that loops through each layer and lists average, max, min etc. drawtimes for each layer.

I've also considered adding other properties to the layerextension to monitor for things like cpu, disk i/o, etc. but never got around to it.

  • Nice, thanks! My initial research had me learning in this direction as well, although I wonder if using IActiveViewEvents.BeforeItemDraw and AfterItemDraw (remembering to enable IViewManager.VerboseEvents) as in this answer might be simpler although perhaps there is a performance hit; any thoughts on that?
    – blah238
    Commented Mar 16, 2012 at 23:50
  • Oh -- there is no BeforeItemDraw event... that would put a quick end to that idea!
    – blah238
    Commented Mar 17, 2012 at 1:01
  • Another thought, how do you account for when the user cancels the drawing operation (e.g. by clicking or pushing Escape)?
    – blah238
    Commented Mar 17, 2012 at 1:29
  • I was using this only to benchmark the drawing speeds of several different layers, not for use in production where things like drawing cancel happens. Maybe you could check to see if ITrackCancel.Continue() returns true when AfterLayerDraw gets called. Commented Mar 18, 2012 at 1:56
  • I've gotten this working with feature layers but raster layers don't seem to be firing the Before/AfterLayerDraw events. Have you had any luck with raster layers?
    – blah238
    Commented Mar 22, 2012 at 20:07

PerfQAnalyzer does just that. From that page:

In the Spring of 2012 we released the PerfQAnalyzer tool, which assists users in capturing render and edit times within ArcGIS for Desktop. This tool is a free, unsupported, downloadable tool offered to the Esri user community which can be run from within ArcMap (as an add-in) or as a stand-alone ArcGIS Engine application. Most users will find the ArcMap add-in the most useful. We have received great feedback regarding this tool and have since released a new version of the tool which is now available for download. The following enhancements have been made to assist users in calibrating ArcGIS for Desktop performance:


Unfortunately it appears that the ILayerExtensionDraw.BeforeLayerDraw and AfterLayerDraw events are only fired by feature and network layers (see wguidry's post here) and I need to support raster layers, map/image services, mosaic datsets, etc.

So in a nutshell here is what I ended up doing. Thanks @Kirk again for the ideas!

Created the following classes:

  • Timing: Stores the layer name, draw phase and elapsed time for a drawing event
  • TimingSequence: Stores all the timings in a drawing sequence
  • TimingSession: Stores all of the timing sequences in a timing session and manages the Stopwatch.

A timing session is started and stopped by a toggle button. When the timing session starts I enable IViewManager.VerboseEvents and disable it when the timing session ends.

I reset and start the Stopwatch at the start of a drawing sequence as indicated by IActiveViewEvents.ViewRefreshed and instantiate a new TimingSequence object.

Then, as each layer draws for a specific phase, I listen for IActiveViewEvents.AfterItemDraw, stop the Stopwatch, check that ITrackCancel.Continue() returns true (false indicates drawing was canceled) and record the layer name, phase and elapsed time in a new Timing object and add it to the current TimingSequence, and reset/restart the Stopwatch.

I only add a timing sequence to the timing session when IActiveViewEvents.AfterDraw fires in the esriViewForeground phase (the last drawing phase).

When the user ends the timing session by toggling the button again, I report the results (ideally it would be something nicer than an ugly MessageBox as it is now). It seems to be working smoothly though.

Problem: The AfterItemDraw event only seems to fire for layers in the root of the table of contents, not nested sublayers, so if you want individual measurements for a layer it must be moved into the root of the TOC and not within a group layer. See linked question: ArcObjects: AfterItemDraw only fires for layers in the root of TOC


I think you should try mxdperfstat:

An ArcGIS Engine command line tool to diagnose typical mxd performance problems.

Supports ArcGIS 9.3, 10, 10.1, 10.2, 10.3 versions.


Esri has an unsupported add-in to arcmap called PerfQAnalyzer. It can measure the draw time for different layers, it also has a scripting feature and can be run in a standalone mode as well.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.