Тема: Можно ли ускорить выполнение программы VBA

Здравствуйте.

Вопрос такой. Я написал программу по рисовке плана участка применительно к железной дороге. Программа читает несколько текстовых файлов и в зависимости от общего объема данных тратится определенное время на выполнение кода программы. Например, если 1000 исходных точек с параметрами, то это 3 минуты, 10000 точек, то это 25 минут, 25 тысяч точек, то сейчас в процессе вычислений около половины точек уже затрачено 30 минут.

В моем компе стоит 2 гига оперативки и процессор Core 2 Duo E6550 @2.33 ГГц. Сейчас это железо уже морально устарело. Но...

Гляжу в диспетчере задач на полную работает только одно ядро процессора из двух. В приципе такое я видел и при работе других программ, но некоторые программные продукты грузили процессор полностью (оба ядра). Может и на VBA можно озадачить процессор на обоих ядрах полностью?

Если знаете, подскажите как это сделать.

Спасибо.

Re: Можно ли ускорить выполнение программы VBA

AutoCAD до 2011 версии однопоточный. (дальше пока неизвестно). Т.е. ускорить сможешь только процессы вне AutoCAD(чтение файла,расчеты), выполняя их в другом потоке.
Скорее всего, тебе поможет только перенос задачи c VBA на .NET или ObjectARX.

Re: Можно ли ускорить выполнение программы VBA

.NET ? Это по-моему тот же VBA, только по-другому. Я прав? А основа программирования ObjectARX на каком языке программирования?

Re: Можно ли ускорить выполнение программы VBA

Владимир Линейцев пишет:

.NET ? Это по-моему тот же VBA, только по-другому. Я прав? А основа программирования ObjectARX на каком языке программирования?

.NET, как и VBA и все остальное может работать с акадом через com.
А может и через objectarx (основные библиотеки acmgd.dll и acdbmgd.dll - обертки для objectarx).

Если перепишешь на NET.arx то скорее всего скорость вырастет.
Да и перспективы появятся.
VBA отмирающая технология.

(изменено: Дмитрий Привалов, 2 ноября 2010г. 12:54:23)

Re: Можно ли ускорить выполнение программы VBA

VB, VBA, Delphy работают через COM. ...COM это "медленно"(ест-но относительно большого количества создаваемых объектов) Т.е. у тебя скорее всего не сама логика программы медленно работает, а присутствует "медленная" связь с Автокадом.
Перепишешь программу на
VB.NET, c#.NET, и т.д. через (основные библиотеки acmgd.dll и acdbmgd.dll ), уберешь "медленную" связь с автокадом.

....а вообще, чтобы точно понять, что у тебя тормозит работу... вставь таймеры на каждую операцию.
В C# это делается так:

using System.Diagnostics;
Stopwatch swatch = new Stopwatch();
swatch.Start(); // старт
....твоя операция
swatch.Stop();
MessageBox.Show("Время выполнения: " + swatch.ElapsedMilliseconds);

...получишь например такие результаты
1. Чтение файла в массив 30 сек
2. Поиск в массиве необходимых данных 10 минут
3. Связывание с автокадом и построение 10 минут

...уже поймешь что 1 пункт хоть заоптимизируйся, много не выйграешь, а с 2,3 можно поколдовать.
...если перейдешь на NET, ObjectARX, ты воздействуешь только на 3 пункт ;)

Re: Можно ли ускорить выполнение программы VBA

Мне кажется, что дело не в технологиях. Судя по задаче, нужен более совершенный алгоритм. Т.е., если предстоит обрабатывать большой объем данных, то не следует решать задачу в лоб. Это справедливо для всех языков программирования и для всех технологий. В данной конкретной ситуации присоединяюсь к Дмитрию Привалову "....а вообще, чтобы точно понять, что у тебя тормозит работу... вставь таймеры на каждую операцию."

Re: Можно ли ускорить выполнение программы VBA

Я и сейчас знаю что у меня "медленный" блок видимо связь с автокадом. Смысл этой связи вот такой:
1. предварительно прочитан объем данных в массив - набор точек NomerPoint,X,Y,H,kod
2. на чертеж вынесены индексы этого массива
3. вокруг каждой расчетной точки в радиусе R определены и отсортированы другие точки посредством SelectionSet - это есть связь с ACAD.
Чисто математически мне кажется это долго делать, если объем данных большой (более 10-15 тыс.точек), потому что нужно сначала рассчитать полярные расстояния от расчетной точки до всех остальных и отбросить те, расстояние до которых более R. На больших объемах данных это сильно тормозит процесс определения номеров точек в радиусе R. Это проверено! Через SelectionSet сейчас это реально быстрее. Но все равно данных 25 тыс.точек -> время работы программы 1 ч 20 мин. Хотелось бы побыстрее.
Может у кого есть математический алгоритм, позволяющий значительно ускорить процесс выбора группы точек вокруг каждой расчетной на расстоянии R?
4. выполнены определенные вычисления
5. построен чертеж - не очень сильно тормозит на фоне других процедур. В ACAD выведено 175 тыс.примитивов
6. создано несколько текстовых файлов


А можно ссылку на программу и документацию VB.NET?

LeonidSN пишет:

Т.е., если предстоит обрабатывать большой объем данных, то не следует решать задачу в лоб.

Я уже давно отказался от решения задачи в лоб и за 5 лет колдовства над программой добился таких результатов (1 ч 20 мин) с постепенным усложнением и наворачиванием. На первых моих алгоритмах мне кажется на это ушло бы не менее 5 часов.
В некоторых случаях пришлось применять алгоритмы быстрой сортировки, написанные изначально для линейных массивов, к прямоугольным массивам и т.д. Вот теперь я вновь пытаюсь ускорить вычислительный блок (пункт 3).

Хочу сказать что все объекты для которых я строю чертежи ACAD - это в основном линейные объекты - железнодорожные станции и железнодорожные перегоны, а расстояние R=250 м - это максимальная величина габарита от съемочной точки до пути (ближайшего или любого другого). Координаты точек получены в результате геодезической съемки полосы вдоль ж.д.путей в пределах 100-200 м в обе стороны.

Re: Можно ли ускорить выполнение программы VBA

<quote> Мне кажется, что дело не в технологиях </quote>
И в этом тоже конечно дело. Но использование Net.Arx по большинству операций даст очень большой выигрыш в скорости по отношению к VBA при одном и том же алгоритме (проверено на практите). Потом Vba это тупиковый путь (сам с него начинал и ушел из-за его ограниченности и отношению к нему Autodesk).  А net дает огромные перспективы и возможности. На net можно делать серьезные вещи, а не любительские, которые позволяет сделать VBA или Lisp под Акад.
Ссылки:
http://sites.google.com/site/bushmansnetlaboratory/
http://through-the-interface.typepad.com
http://www.theswamp.org/
Ну и конечно нужно книгу по dotnet платформе и объектно-ориентированному программированию.

(изменено: Дмитрий Привалов, 3 ноября 2010г. 07:53:44)

Re: Можно ли ускорить выполнение программы VBA

А можно ссылку на программу и документацию VB.NET?

Бесплатная среда разработки
http://www.microsoft.com/express/Downloads/
ObjectARX...внутри еще и для .NET документация и примеры
http://usa.autodesk.com/adsk/servlet/it … ;id=785550
Подробности смотри в разделе форума .NET

И в этом тоже конечно дело. Но использование Net.Arx по большинству операций даст очень большой выигрыш в скорости по отношению к VBA при одном и том же алгоритме (проверено на практите). Потом Vba это тупиковый путь (сам с него начинал и ушел из-за его ограниченности и отношению к нему Autodesk). А net дает огромные перспективы и возможности. На net можно делать серьезные вещи, а не любительские, которые позволяет сделать VBA или Lisp под Акад.

1. Если смотреть по перспективности .NET и ObjectARX предпочтительнее, чем VBA и LISP.
2. По скорости отрисовки в AutoCAD и работы с БД чертежа....тоже .NET и ObjectARX. Но стоит учитывать задачу например вставка форматок и на LISP не тормозит....переписывать из-за скорости на .NET смысла нет). В конкретно обсуждаемой задаче смысл наверно есть)
3. По скорости расчетов, логических операций, работе с файлами, массивами C++,.NET,VBA примерно одинаковы. Стоит избегать "ГОВНОКОД", который из С++ может сделать черепаху, более медленную чем LISP. А также стоит выбирать правильные алгоритмы, массивы, принципы буферизации и т.д.
4. Всегда учитывайте время разработки и обучения, т.к. это лимитированный ресурс.

Re: Можно ли ускорить выполнение программы VBA

1. предварительно прочитан объем данных в массив - набор точек NomerPoint,X,Y,H,kod
2. на чертеж вынесены индексы этого массива
3. вокруг каждой расчетной точки в радиусе R определены и отсортированы другие точки посредством SelectionSet - это есть связь с ACAD.

...вот здесь у меня подозрения на не оптимальность алгоритма.
Считываешь в массив, выносишь в чертеж, выбираешь в чертеже.
...Скорость выборки из массива в несколько раз выше чем из БД чертежа ... может ты сможешь выполнить выборку из массива и расчеты внутри программы, а потом уже связываться с AutoCAD?

Re: Можно ли ускорить выполнение программы VBA

Дмитрий Привалов пишет:

3. По скорости расчетов, логических операций, работе с файлами, массивами C++,.NET,VBA примерно одинаковы.

Нет. Особенно это касается расчетов. Чтение данных из чертежа может быть примерно одинаковым, хотя VBA наиболее медленный в силу общения с AutoCAD через COM-интерфейс.

(изменено: Дмитрий Привалов, 3 ноября 2010г. 11:38:32)

Re: Можно ли ускорить выполнение программы VBA

Александр Ривилис пишет:

Нет. Особенно это касается расчетов.

Александр! Может свою статистику выложите или может ссылкой поделитесь?
При собственном сравнении c++ и с# ...получал разницу 3-10%(самого языка, а не связки с автокадом) ....что считаю не существенным(для моего объема данных).
....может быть у Вас были интересные большие расчетные задачи....в которых был существенный выигрыш 30% и более? ....это пригодится тем, кто только начал планировать комплексную задачу, и еще не решил на каком языке ее реализовывать?

Re: Можно ли ускорить выполнение программы VBA

Вечером размещу информацию с курсов по ObjectARX...там есть некоторое сравнение по скорости VB, VBA, Lisp, C#, ObjectARX. Но хотелось бы побольше информации.

Re: Можно ли ускорить выполнение программы VBA

Дмитрий Привалов пишет:

При собственном сравнении c++ и с# ...получал разницу 3-10%(самого языка, а не связки с автокадом)

Я в первую очередь сравнивал C++ с VBA, а не C++ и C#. VBA значительно уступает по скорости. Если сравнивать C++ (native, а не managed) с C# (и .NET вообще) то C++ шустрее в силу того, что можно избежать дополнительных проверок на валидность данных (безопасность), которые C# делает всегда. И вообще на C++ мы получаем практически чистый машинный код в отличие от технологии .NET
По большому счету все зависит от того что именно нужно писать.
Вот пример сравнения числовых алгоритмов: http://www.cherrystonesoftware.com/doc/ … rmance.pdf

Re: Можно ли ускорить выполнение программы VBA

Владимир Линейцев пишет:

Может у кого есть математический алгоритм, позволяющий значительно ускорить процесс выбора группы точек вокруг каждой расчетной на расстоянии R?

У меня когда-то была задача: выбрать определенные объекты внутри прямоугольной полилинии. Использовал метод select (в сущности, классика жанра):

' Add all object to the selection set that lie within a crossing of (28,17,0) and
    ' (-3.3, -3.6,0) 
    Dim mode As Integer
    Dim corner1(0 To 2) As Double
    Dim corner2(0 To 2) As Double
    
    mode = acSelectionSetCrossing
    corner1(0) = 28: corner1(1) = 17: corner1(2) = 0
    corner2(0) = -3.3: corner2(1) = -3.6: corner2(2) = 0
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ssetObj.Select mode, corner1, corner2, intDXF, FilterValue

Владимир, может и тебе стоит использовать квадрат вокруг расчетной точки, а не окружность?

Re: Можно ли ускорить выполнение программы VBA

Вот обещанные результаты тестов
http://s014.radikal.ru/i326/1011/af/3720162b5531.png
http://s006.radikal.ru/i215/1011/99/b65548177182.png
http://s006.radikal.ru/i214/1011/54/530de995cc12.png
http://s006.radikal.ru/i213/1011/94/b4b0cef79331.png

Re: Можно ли ускорить выполнение программы VBA

LeonidSN пишет:

Владимир, может и тебе стоит использовать квадрат вокруг расчетной точки, а не окружность?

Я думал об этом, но исходная конфигурация точек на чертеже может быть любая и если квадрат станет параллельно этой конфигурации, то часть точек в область выбора може и не попасть. А выбор я именно с помощью Select и делаю, только внутри 16-ти угольника.

Дмитрий Привалов пишет:

...Скорость выборки из массива в несколько раз выше чем из БД чертежа ...

Я это понимаю, только пока не нашел быстрого алгоритма, потому и справшиваю на форуме

(изменено: Александр Ривилис, 4 ноября 2010г. 12:21:03)

Re: Можно ли ускорить выполнение программы VBA

Владимир Линейцев пишет:

Я это понимаю, только пока не нашел быстрого алгоритма, потому и справшиваю на форуме

Пусть у тебя есть множество точек M и точка P(x0,y0), относительно которой нужно выбрать все точки из M, расстояние до которой не больше L (я говорю не о точках AutoCAD, а о геометрических точках). В первом проходе можно получить множество точек M1, для которых x0-L/2 <= x <= x0+L/2 и y0-L/2 <= y <= y0+L/2 а уже из него найти те которые находятся на расстоянии <= L от точки P.

Re: Можно ли ускорить выполнение программы VBA

По-моему это слишком просто - простой перебор, а, значит, и слишком долго. Для каждой точки найти список точек, находящихся в квадрате LxL в первом проходе, а заетм во втором проходе поискать нужный список. Считаем количество операций только по первому проходу. Общий объем точек 25000 шт. Nопер1 = 25000 х 25000 = 625 млн.опер. Если добавим второй проход (1-я выборка примерно 200 шт в квадрате LxL), то Nопер2 = 625 млн.опер. x 200 = 125 млрд.опер. При частоте процессора 2.33 ГГц это составит 53 сек только на один перебор значений циклов. Если добавить всю необходимую математику, то будет наверное раз в 100 больше, т.е. 1,5 часа. Может быть я ошибаюсь. Если у вас есть такая статистика подскажите, далеко ли я от истины.

(изменено: Александр Ривилис, 4 ноября 2010г. 18:53:55)

Re: Можно ли ускорить выполнение программы VBA

Владимир Линейцев пишет:

Nопер2 = 625 млн.опер. x 200 = 125 млрд.опер.

Вот тут ты не прав (IMHO). Тут у тебя только 25000 x 200. Если я правильно понял то, что тебе нужно сделать.

Re: Можно ли ускорить выполнение программы VBA

Мне нужно вокруг КАЖДОЙ из 25000 точек найти точки в радиусе R метров. Их примерное количество в этом радиусе будет около 200 шт.

(изменено: Александр Ривилис, 4 ноября 2010г. 22:48:00)

Re: Можно ли ускорить выполнение программы VBA

В первом двойном цикле ты уже для каждой из 25000 точек (P) нашел соответствующие 200 точек (M) , лежащие в прямоугольниках 2*R x 2*R, где R-радиус окружности. На это у тебя уйдет в худшем случае 25000 * 25000 вычислений (точнее 25000*25000/2, т.к. ты не будешь дважды проверять одни и те же пары точек).
В результате для каждой точки P(i) у тебя будет массив M(i), в котором только те точки, которые попали в прямоугольник.
Во втором двойном цикле ты из отобранных для каждой точки P(i) из набора M(i) удаляешь те точки, которые не попадают в окружность радиуса R. Так вот этот цикл будет 25000 x 200.
В принципе эти операции (т.е. сразу проверять на попадание в круг, не проверяя на попадание в прямоугольник) можно было бы и совместить, но операции умножения и извлечения корня (для получения расстояния) более медленные.
Кстати в M(i) для экономии памяти можно хранить не точки, а индексы (номера) точек массива P.
Короче вариантов оптимизации масса.

Re: Можно ли ускорить выполнение программы VBA

Спасибо попробую.

Re: Можно ли ускорить выполнение программы VBA

Владимир Линейцев,
А если пользоваться не массивами? А средствами для работы с базами данных. Например ADO. Фильтрацию и расчёты проводить запросами. И уже готовые результаты сбрасывать в AutoCAD.

Re: Можно ли ускорить выполнение программы VBA

У меня стояла задача работы с поверхностью, описанной 3,2 млн. точек
Результаты работы:
1. В Civil3D загружается медленно, выползают ошибки при работе.(опробованы 2007,2010,2011 версии)
2. В Кредо подгрузку в БД не дождались, ибо БД при таких объемах это медленно.
3. Нормально обрабатывается только в собственных массивах языка(в моем случае C#).

Владимир если хочешь быстро обработать большие объемы данных, никакой переборки из базы данных или AutoCAD, только подгрузка в массив!
БД, в том числе чертеж AutoCAD используй для подгрузки, одиночного прохода по элементам массива....но никак не для нескольких циклов выборок.

В твоем случае ...если никак не отказаться от перебора точек вне автокада:
For i= ....
...считывание точки из чертежа
For i2=...
...цикл проверок подходит/не подходит по координатам(условия загони в заранее подготовленный массив...у тебя массив центр круга и радиус)  ;)