Форум пользователей Visio

Форум по вопросам применения и программирования в Visio
Текущее время: 21 июн 2018, 12:22

Часовой пояс: UTC + 3 часа [ Летнее время ]


Правила форума


При размещении файлов предпочтительным является формат vsd (а не vsdx/vsdm)



Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Групповые операции медленнее одиночных?
СообщениеДобавлено: 05 мар 2018, 12:46 
Не в сети
Administrator

Зарегистрирован: 30 авг 2009, 11:02
Сообщений: 1130
Очков репутации: 100585

Добавить очки репутацииУменьшить очки репутации
По умолчанию считал, что на групповые операции (типа SetFormulas) тратится меньше времени, чем на соответствующее количество одиночных (типа .Formula=).
См., например https://blogs.msdn.microsoft.com/mailan ... ance-tips/
Цитата:
SetFormulas and SetResults let you set multiple formulas and results (respectively) in one call. Again, this is important for .NET applications especially to minimize traffic across processes.

Оказалось, что это как минимум не всегда так.
На другом форуме встретилась задача, в которой выполняется поворот нескольких тысяч шейпов в Visio Addin на C#. Были попробованы оба метода.
Неожиданно групповая операция оказалась медленнее примерно в два раза.
Возможно, это особенность .NET. Или связано именно с Addin на C#...
Если будут другие наблюдения в этом плане, прошу сообщить здесь.
--------------------------
Не исключено, что такая особенность может быть связана с большим количеством шейпов.
Возможно также, что сильно повлияло то, что при подготовке массива для групповой операции идентификаторы выбирались путем одиночных обращений к ActivePage.Shapes. А если бы шейпы были нарисованы перед этим с использованием DropMany, то массив идентификаторов был бы уже готов и тогда групповая операция дала бы заявленный эффект ускорения.


Пожаловаться на это сообщение
Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Групповые операции медленнее одиночных?
СообщениеДобавлено: 05 мар 2018, 14:44 
Не в сети
Administrator

Зарегистрирован: 30 авг 2009, 11:02
Сообщений: 1130
Очков репутации: 100585

Добавить очки репутацииУменьшить очки репутации
Добавлю еще несколько измерений...
Во-первых, программы. Выполнение одиночными операциями:
Код:
        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 градусов). В последнем случае все одиночные операции вообще в секунду укладываются.


Пожаловаться на это сообщение
Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Групповые операции медленнее одиночных?
СообщениеДобавлено: 05 мар 2018, 15:29 
Не в сети
Ветеран

Зарегистрирован: 21 окт 2011, 12:01
Сообщений: 892
Откуда: г. Екатеринбург
Использую Visio c: 2011
Очков репутации: 120

Добавить очки репутацииУменьшить очки репутации
можно вопрос: а зачем GC.Collect() два раза вызывается?


Пожаловаться на это сообщение
Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Групповые операции медленнее одиночных?
СообщениеДобавлено: 05 мар 2018, 15:31 
Не в сети
Administrator

Зарегистрирован: 30 авг 2009, 11:02
Сообщений: 1130
Очков репутации: 100585

Добавить очки репутацииУменьшить очки репутации
Не знаю.
nbelyh посоветовал вот здесь
http://visguy.com/vgforum/index.php?topic=8314.0


Пожаловаться на это сообщение
Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Групповые операции медленнее одиночных?
СообщениеДобавлено: 05 мар 2018, 15:48 
Не в сети
Ветеран

Зарегистрирован: 21 окт 2011, 12:01
Сообщений: 892
Откуда: г. Екатеринбург
Использую Visio c: 2011
Очков репутации: 120

Добавить очки репутацииУменьшить очки репутации
мне вот еще интересно на каких версиях визио это тестировалось. и есть ли разница новых и старых версий. возможно SetFormulas поломали в новых визио...


Пожаловаться на это сообщение
Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Групповые операции медленнее одиночных?
СообщениеДобавлено: 05 мар 2018, 16:05 
Не в сети
Administrator

Зарегистрирован: 30 авг 2009, 11:02
Сообщений: 1130
Очков репутации: 100585

Добавить очки репутацииУменьшить очки репутации
Я смотрел на всем 2010. И Visio, и Visual Studio.
Но тут не подходит громкое слово "тестировалось". Просто ткнулся и удивился. Ну, немного посмотрел вокруг...
Кстати, если это происходит только при очень большом количестве шейпов, то может так и всегда было. Просто это обычно никому не нужно. Поэтому и захотелось узнать, натыкался ли кто-нибудь на что-то подобное.


Пожаловаться на это сообщение
Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Вы можете создать форум бесплатно PHPBB3 на Getbb.Ru, Также возможно сделать готовый форум PHPBB2 на Mybb2.ru
Русская поддержка phpBB