Добавлю еще несколько измерений...
Во-первых, программы. Выполнение одиночными операциями:
Код:
public void Command1()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int operationCounter = 0;
Visio.Page pg = Globals.ThisAddIn.Application.ActivePage;
int undoId = pg.Document.BeginUndoScope("set angle");
int shpCount = pg.Shapes.Count;
for (int i = 0; i < shpCount; i++)
{
pg.Shapes[i + 1].CellsSRC[(short)Visio.VisSectionIndices.visSectionObject,
(short)Visio.VisRowIndices.visRowXFormOut,
(short)Visio.VisCellIndices.visXFormAngle].Formula = "15 deg";
if (operationCounter++ > 500)
{
GC.Collect();
GC.Collect();
operationCounter = 0;
}
}
pg.Document.EndUndoScope(undoId, true);
GC.Collect();
GC.Collect();
stopwatch.Stop();
string s = stopwatch.ElapsedMilliseconds.ToString();
MessageBox.Show(s);
}
И групповой операцией:
Код:
public void Command5()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Visio.Page pg = Globals.ThisAddIn.Application.ActivePage;
int undoId = pg.Document.BeginUndoScope("set angle");
Array src = Array.CreateInstance(typeof(short), pg.Shapes.Count * 4);
Array val = Array.CreateInstance(typeof(object), pg.Shapes.Count);
Array IDs = Array.CreateInstance(typeof(short), pg.Shapes.Count);
int shpsCount = pg.Shapes.Count;
for (int i = 0; i < shpsCount; i++)
{
IDs.SetValue((short)pg.Shapes[i + 1].ID, i);
}
stopwatch.Stop();
string s0 = "get IDs " + stopwatch.ElapsedMilliseconds.ToString();
stopwatch.Start();
for (int i = 0; i < shpsCount; i++)
{
src.SetValue((short)IDs.GetValue(i), i * 4);
src.SetValue((short)Visio.VisSectionIndices.visSectionObject, i * 4 + 1);
src.SetValue((short)Visio.VisRowIndices.visRowXFormOut, i * 4 + 2);
src.SetValue((short)Visio.VisCellIndices.visXFormAngle, i * 4 + 3);
val.SetValue("30 deg", i);
}
stopwatch.Stop();
string s1 = "prepare array " + stopwatch.ElapsedMilliseconds.ToString();
stopwatch.Start();
pg.SetFormulas(ref src, ref val, (short)Visio.VisGetSetArgs.visSetUniversalSyntax);
stopwatch.Stop();
string s2 = "SetFormulas " + stopwatch.ElapsedMilliseconds.ToString();
pg.Document.EndUndoScope(undoId, true);
stopwatch.Start();
GC.Collect();
GC.Collect();
stopwatch.Stop();
string s3 = "GC.Collect " + stopwatch.ElapsedMilliseconds.ToString();
MessageBox.Show(s0 + "\n " + s1 + "\n " + s2 + "\n " + s3);
}
Измерения при групповой операции:
get IDs - 728
prepare array - 731
SetFormulas - 1975
GC.Collect - 1982
Получение идентификаторов вынесено в отдельный блок.
Работа аддина завершается за 2 секунды.
НО! после этого Visio еще висит 15 секунд. По-видимому, переваривает полученный массив и рендерит изображение.
С помощью одиночных операций та же работа выполняется за 2,5 секунд (отсчет таймера в аддине). И еще пару секунд проявляется изображение.
Дополнительное наблюдение. Если реально изменяется значение формулы, то операция выполняется примерно в 3 раза медленнее, чем запись того же самого значения. (То есть было 15 градусов и пишем 15 градусов). В последнем случае все одиночные операции вообще в секунду укладываются.