|
||
| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны | Справка по форуму | Файлообменник | |
|
Поиск в этой теме |
31.07.2004, 21:47 | #1 | |
LISP - оптимизация кода
Штаб
Регистрация: 21.08.2003
Сообщений: 943
|
||
Просмотров: 2586
|
|
||||
сисадмин Регистрация: 26.08.2003
Самара
Сообщений: 1,022
|
Не вникая в сам алгоритм работы программы:
1. Функция *error* переопределена. Это хорошо. Плохо то что это переопределение является глобальным. Если так сделать в нескольких программах и загрузить их одну за другой - то реальной функцией *error* будет та, которая загружена последней. Чтоб не париться с восстановлением - можно энтот *error* просто локализовать. Например, так: Код:
Цитата:
3. Наверно луччше всеж проверить выбранный примитив перед его модификацией. А заодно и слой (на блокировку), на котором он размещен... Чтоб прога не вылетала. Впрочем, дело хозяйское. Как другой вариант решения этой проблемы - функция (vl-catch-all-apply). Если даже не удалось выполнить недозволенное - прога не вылетит. А проверку на "не удалось" можно сделать функцией (vl-catch-all-error-p) и просто выводить сообщение через (princ) или (alert). Последнее действует отрезвляюще и пробуждающе Так что, похоже, не сокращать, а добавлять еще придется. :wink: |
|||
|
||||
Сообщений: n/a
|
Всё, что написал vk, кроме полезности переопределения *error* - совершенно правильно. Переопределение *error*, в этой ситуации - приносит только вред (про это, как раз, всё - точно). Прежде, чем её переопределять, надо задуматься - а какие задачи она будет решать, ну и делать это надо правильно. Кроме того, забудте про существование exit/quit - облегчите жизнь себе и коллегам.
Код, в первом приближении, может быть, примерно, таким (очень наскоро): Код:
|
|||
|
||||
Сократить код в реальных приложениях, считаю можно только использованием библиотечных функций.
Хороший тон - проверка входных значений, сохранение введенных данных для последующего использования в качестве умолчаний. Библиотечные функции, также хорошо делать не зависящими от типа входных значений, (примитив, список... ) в разумных пределах конечно же. Обязательно также корректное восстановление переменных среды при error / завершении работы. Alert - имеет смысл выводить _только_ уж при совсем бредовых действиях пользователя. Либо перед действиями которые нельзя отменить. Alert - для теток. По поводу *error*. Лучше использовать свой обработчик ошибок. Переопределять ее локально имеет смысл, только если необходимо выполнить действия, которых нет в своем. P.S. Неплохая библиотека Stdlib. http://xarch.tu-graz.ac.at/autocad/stdlib/ |
||||
|
||||
сисадмин Регистрация: 26.08.2003
Самара
Сообщений: 1,022
|
Вот споры то... Переопределять *error* или нет....
Считаю что в данном случае в своем *error* следует прикрыть АКАДовское сообщение о прерывании функции по Esc и сделать тихий выход. Это первое. Второе - если возникнет желание реализовать группы для UNDO - то возможно, придется в *error* также сделать и откат. Все это применительно к конкретной данной ситуации (код в первом постинге - рекурсивный вызов без условий для выхода). Во многих реальных случаях переопределение действительно не нужно. |
|||
|
||||
Сообщений: n/a
|
По обработке ошибок см.
http://www.kurganobl.ru/cad/book.jsp...=357&tn=main#b - в контексте окружающих материалов. Реализация обработчиков ошибок см. http://www.kurganobl.ru/cad/book.jsp...=726&tn=main#b Особенно интересно использование ловушки ошибок ru-error-catch в сочетании как с методами ActiveX, так и с vl-cmdf. Реализации в функциях ввода данных см. http://www.kurganobl.ru/cad/book.jsp...nt=116&tn=main При их системном использовании обращение к *error* практически не происходит Все это в комплексе позволяет предотвратить подавляющую часть ошибок в программах, позникающих при "неправильных" действиях "неправильных" пользователей. Алгоритмические ошибки, конечно не предотвращаются, хотя иногда могут быть отловлены и сбои, вызванные неверным алгоритмом. |
|||
|
||||
Регистрация: 21.08.2003
Штаб
Сообщений: 943
|
Всем спасибо за обсуждение, но вопрос в другом:
несколько раз бывало предлагали свои коды начинающие программисты (типа меня) и люди типа Эдуарда, Fantomas'a, kos'a, vk и др. У вторых код был лаконичнее и красивше. Поэтому переформулирую вопрос свой так: какие места в Лисп-программе можно переписать с меньшим количеством строк. Может быть применить несколько другой алгоритм. Другие функции. Ведь начинающие как работают: надо выполнить то-то. Для этого можно использовать вот ту функцию в сочетании с вон той. И не знают, что для выполнения данного действия уже существует функция. Работающая быстрее и стабильнее. Вот в чем вопрос. |
|||
|
||||
Сообщений: n/a
|
Цитата:
Иногда красивый, супероптимизированный код может стать полностью непонятным. Особенно это относится к разному прикладному рисованию. Последовательное вычисление координат точек рисунка и последующая отрисовка по ним сделают код понятным для человека, хотя его можно оптимизировать, избавившись от переменных. Выигрыш в этом случае небольшой, скорее "из прынцыпа", проблем может быть больше. В общем плане для улучшения красоты кода надо копать mapcar, lambda и т.п. Цитата:
Приведенный в первоначальном вопросе код Alaspher оптимизировал, но "строк" стало больше. Однако они намного надежнее. Это же можно написать короче, используя, например функции ru-xxx (ссылки давал в темах рядом) для выбора примитива (в функции будет спрятаны проверки на ошибку выбора, тип примитива, блокировку слоя), ввод дистанций и модификацию примитива. Вот тогда будет и просто, и надежно. Да еще, если выявится ошибка в библиотечной функции, можно будет исправить только одно место, не корректируя множество программ. Alaspher об этих функциях знает, но он использовал только стандартные, чтобы было понятно всем. Что еще можно с этим кодом сделать неясно, так как неясна конечная цель. Это ведь не изменение выдавливания, а что-то другое. Например, построение рельефа. Может быть все в принципе не так можно сделать. |
|||