habrahabr

Почему я пишу свои алгоритмы в 95% случаев, и буду и дальше разрабатывать кодовые велосипеды

  • суббота, 19 марта 2016 г. в 02:20:45
https://habrahabr.ru/post/279419/
  • Программирование


Это ответ на публикацию «А нужно ли знать программисту алгоритмы?».

Так почему я пишу свои алгоритмы в 95% случаев и буду их и дальше писать?

Дабы быть кратким, сразу приведу конкретику в моем случае (весьма экзотическом), но отмечу что есть немало случаев-аналогов. Если в вашей практике нет случая-аналога — поздравляю, вам не нужно заморачиваться велосипедами. Возьмите с полки пирож... Возьмите готовый код, это реально отличный вариант для RAD, да и просто для потоковой разработки, где время — деньги, а специальные требования отсутствуют.

Я разработчик экспериментальной системы управления крылатым беспилотником.

1. В моем коде не должно быть никаких «черных ящиков»


Речь даже не идет про скомпилированные библиотеки (они табу изначально: весьма вероятен неэффективный и грязный код, да и потенциально возможны «закладки» в нем). Речь про фрагменты кода, найденные в интернете, которые не до конца понимаю. Моя система должна быть абсолютно понятной по алгоритму работы в первую очередь мне, как ведущему разработчику, т.к. именно я должен буду находить проблемное место и исправлять его.

2. У меня есть всего 160 мегагерц и 300 кб ОЗУ


Я не могу позволить себе в первую очередь тратить мегагерцы, а во вторую килобайты.

Современные разработчики под «большие машины» избалованы обилием ресурсов. Они не оптимизируют код и склонны делать избыточные конструкции в стиле «и так работает шустро/компилятор все оптимизирует». Это расслабляет, и зачастую делает боле-менее нормальный код для больших компьютеров, нежизнеспособным в чужой экосистеме (например, на микроконтроллерах (МК)).

Код для МК потому должен максимально полно раскрывать и рассчитывать все, что используется не раз в коде. Чтото вроде очень глобальной оптимизации. Потому даже если берется решение «из форумов и stackoverflow», оно проверяется и оптимизируется (простейший пример такой оптимизации — замена обычных тригонометрических функций на табличные, предрасчитанные).

Внутри моего кода используется очень много абсолютных переходов типа goto, и все лишние расчеты максимально срезаются. Хороший чужой код, как правило, медлителен и неповоротлив. Например, техзрение. Отличная библиотека OpenCV — но куда мне ее впихивать? Это же кодовый монстр! От всего богатства функций технического зрения мне надо всего лишь определять расстояние до движущихся объектов и их границы. Причем на высокой частоте. Изучайте чужой опыт, но пишите свое.

3. Мой код должен быть быстрым и безопасным с точки зрения ошибок в логике


Очень тяжело проверять чужие коды на безопасность и устойчивость. И всякие cppcheck не помогут. Это хорошие инструменты, но они обнаруживают только технические, но не алгоритмические ошибки, которые в чужих кодах встречаются. Чаще проще написать с нуля, понимая идею и решение, чем адаптировать и переписывать к своим требованиям чужое. Да, это занимает время, но на выходе получаем очень эффективный и безопасный код. Заточенный именно под нужную задачу.

И немножко к личному опыту по изучаемой теме.

4. Еще одна причина работы с велосипедами сугубо отраслевая


В моей индустрии нет готовых (открытых) решений, едва мы уходим от проторенной open source автопилотами дорожки. Например, проблема управления полетом на низком уровне (когда мы уже знаем, какая должна быть траектория и нужно всего лишь совместить положение борта с ней) описана в теоретических трудах как обычная PID цепочка. Все в целом просто, но el diablo скрывается в деталях. В сотнях мелких деталей. Что если отказал двигатель? Если у борта GPS ушел гулять на +-150м? Если инерциальный датчик горизонта из-за вибрации показывает направление на горизонт в районе полярной звезды? И так далее и тому подобное. Вы можете сказать: причем тут PID? Это выходит за его рамки! И будете правы, но задача-то итоговая — именно управление, потому вы смешиваете разные алгоритмы и их элементы в разных функциях. И потому все алгоритмы создаются с нуля, шлифуются и идеализируются именно под конкретную задачу в контексте автоматического управления БПЛА. Получается довольно ядреная спагетти-смесь из кодов, весьма сложная в изменениях, но крайне эффективно решающая задачу.

Известная истина, которую часто забывают (или ленятся вспомнить): эффективность/скорость — это противоположность универсализации. Не прямое противопоставление, но они не на одной чаше весов. Когда создается софт для очень экономичной экосистемы, образно говоря, каждый синус на счету. А уж тем более использование delay(), за которое надо некоторых авторов библиотек «расстреливать» (творческая аллегория) с этим самым delay(), чтобы растягивать процесс. Потому все быстрые функции пишутся in situ, с ограниченной универсальностью, а не берутся готовыми универсальными.

Коллеги, не стесняйтесь создавать велосипеды. Это держит мозг в тонусе и часто позволяет получать нетривиальные решения.

P.S.: Мнение автора может не совпадать с вашим.