Оптимизация работы нахождения ближайшего уровня элемента.

Автор Тема: Оптимизация работы нахождения ближайшего уровня элемента.  (Прочитано 4819 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Alex25Автор темы

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Добрый день. Выделяю все элементы на виде рамкой - получаю 22 тысячи. Нахожу у каждого элемента ближайший уровень снизу. В try обрабатываются- FamilyInstance, в Catch -системные (трубы ,воздуховоды и тд). Имею одну транзакцию. В  начале открываю и в самом конце (после цикла по всем элементам). Если это FamilyInstance нахожу ближайший уровень  - высчитываю новое смещение - и устанавливаю элементу новый уровень - записываю  значение параметра "этаж" с нового уровня в параметр "этаж"  элемента. Если это системное , все аналогично , кроме смещение (его не будет). Пишу много if(ов) так, как есть такие трудности  - точка расчета площади, на грани  и тд ( мне это нужно  для нового смещение). Например, если семейство имеет "точку расчета площади", то я беру не LocationPoint.Z,  а "GetSpatialElementCalculationPoint().Z" и смещение задаю по "BoundingBoxXYZ.Min.Z" , чтобы не "скакало". . Фотографии кода прикладываю. 
Статистика:
- файл ВК 3.5 тысячи- обработал за 2 минуты.
- файл ОВ 22 тысячи - обработал за 1 час 20 минут.
Причем, в начале к каждому елементу применял две транзакции и коллектор искал заново , НО на время это никак не повлияло - 1 час 20 мин , как и был.
С результатом работы, пока вопросов нет, но время хотелось бы сократить.
1 вопрос - как сократить время?
2 вопрос - почему при изменение с двух транзакций на одну общую в программе - результат по времени одинаковый ?





« Последнее редактирование: 20-03-2020, 10:48:07 от Alex25 »

Отмечено как Решение Alex25 20-03-2020, 14:36:47

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В try обрабатываются- FamilyInstance, в Catch -системные (трубы ,воздуховоды и тд).
Если есть возможность - откажитесь от обработки в catch. Обработка прерываний в .NET - это достаточно медленная процедура. По опыту программирования в AutoCAD я в этом убедился. Есть два метода Database.GetObjectId который может вызывать прерывание и метод Database.TryGetObjectId, который не вызывает прерывания, а возвращает false если ничего не нашёл, или true если нашел. Разница в скорости работы в случае если прерывания достаточно часто возникают может быть на порядок, а то и на два...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Alex25Автор темы

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Как  думаете , если заменить try catch на if, будет быстрее?
А как количество if (ов) в программе  влияет на время?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Как  думаете , если заменить try catch на if, будет быстрее?
А как количество if (ов) в программе  влияет на время?
Будет не просто быстрее, а на порядки быстрее если исключение возникает часто. Раскрутка стека исключений очень ресурсоемкая процедура. Поэтому логика программа не должна опираться на исключения. Это действительно должен быть исключительный случай, когда вызывается исключение (т.е. попадаем в блок catch).
Количество if-ов практически никак не влияет на скорость выполнения задачи. Они просто обеспечивают ветвление программы.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Alex25,
Почитай: https://docs.microsoft.com/ru-ru/dotnet/standard/exceptions/best-practices-for-exceptions
Цитата оттуда:
Цитировать
Обработка общих условий без выдачи исключений
Для условий, которые могут возникнуть, но способны вызвать исключение, рекомендуется реализовать обработку таким способом, который позволит избежать исключения. Например, при попытке закрыть уже закрытое подключение возникает InvalidOperationException. Этого можно избежать, используя оператор if для проверки состояния подключения перед попыткой закрыть его.
 C#
if (conn.State != ConnectionState.Closed) { conn.Close(); } 
Если состояние подключения перед закрытием не проверяется, исключение InvalidOperationException можно перехватить.
 C#
try { conn.Close(); } catch (InvalidOperationException ex) { Console.WriteLine(ex.GetType().FullName); Console.WriteLine(ex.Message); } 
Выбор конкретного способа зависит от того, насколько часто ожидается возникновение данного события.
 
  • Используйте обработку исключений, если событие не происходит очень часто, то есть если событие носит действительно исключительный характер и указывает на ошибку (например, в случае неожиданного конца файла). При использовании обработки исключений в обычных условиях выполняется меньше кода.
  • Если событие происходит регулярно в рамках нормальной работы программы, выполняйте проверку на наличие ошибок прямо в коде. Проверка на наличие распространенных условий ошибки позволяет выполнять меньший объем кода благодаря устранению исключений.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Alex25Автор темы

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0


Спасибо, кажется стало быстрее, но приходится отлавливать исключения. Элементов много - затратно по времени.


Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Спасибо, кажется стало быстрее, но приходится отлавливать исключения.
Нужно по-максимуму добиться того, чтобы исключений не было.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Alex25Автор темы

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Это магия ?? в 11,5 раз стало быстрее , после замены try catch на if

Спасибо большое

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Это магия ?? в 11,5 раз стало быстрее , после замены try catch на if
Я же предупреждал. :) Стараюсь не лезть в те темы, в которых не разбираюсь. Но в данном случае это общесистемное правило, которое касается всего .NET и даже native C/C++. Нельзя использовать исключения/прерывания в логике работы. Это очень резко уменьшает скорость работы программы.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение