I just discovered today that there are essentially two ways to calculate field values in ArcObjects:
1. Using ESRI.ArcGIS.GeodatabaseUI.ICalculator
:
ITable table = …;
ICursor updateCursor = table.Update(null, false);
ICalculator calculator = new Calculator()
{
Cursor = updateCursor,
Field = …,
Expression = "…"
};
calculator.Calculate();
Marshal.FinalReleaseComObject(updateCursor);
2. Using ESRI.ArcGIS.DataManagementTools.CalculateField
:
var calculateField = new CalculateField()
{
in_table = …,
field = …,
expression = "…",
expression_type = "VB"
};
var gp = new Geoprocessor();
gp.Execute(calculateField, null);
While performance of the two approaches is similar with File GDB tables, I've found that it varies a lot for SDE tables: I've measured a processing speed of 21 milliseconds per row with the former approach (ICalculator
), while geoprocessing requires only 10 milliseconds per row (<50 %).
Does anyone know, or have an educated guess, why ICalculator
is slower?
With the
ICalculator
approach, it doesn't seem to matter whether the cursor used is a recycling one or not. But apparently, an update cursor is required. (I tried using a search cursor, too, but that resulted in warnings and errors — discoverable viaICalculatorCallback
— immediately after callingCalculate
.)Also with the former approach, I tried reducing network bandwidth usage by specifying only the minimum required
SubFields
in theIQueryFilter
used to retrieve the update cursor. Surprisingly, this doesn't improve runtime performance at all.I tried all above methods outside any edit session or explicit transaction.
Calculate
. I discovered this by installing anICalculatorCallback
via theICalculator.Callback
property.