Это перевод оригинальной статьи от Amanda Fawcett.
Разработчики всяческих программ зачастую думают, что продуктивность означает способность писать код как можно быстрее. Но истинная продуктивность в разработке программ сводится к качеству вашего кода.
Руби — это уникальный универсальный язык программирования, на котором можно создать всё что угодно. Руби, хоть он и прост для изучения, требует глубоких знаний и опыта для полного раскрытия его потенциала. Так что сегодня мы собрали наши лучшие советы, хитрости и рекомендации, которые помогут вам максимально эффективно создавать код на Руби.
Совет №1: Избегайте скрытых структур
Скрытые структуры усложняют поддержку вашего кода в долгосрочной перспективе, и лучше их избегать. Взгляните на этот код:
Что за проблема здесь? Мы используем индексы массива, чтобы получить информацию в методе calculate. Однако достаточно сложно сказать, какую именно информацию мы получаем, потому что 0 и 1 совсем не определены и поэтому практически бесполезны.
Мы могли бы использовать константы, чтобы придать больше смысла нашим переменным, как здесь:
Мы также можем избежать скрытых структур Ruby, используя Struct для осмысленного представления данных.
Совет №2: Избегайте while !(not)
Цикл while !(not) используется для проверки кода до тех пор, пока условие не будет выполнено. В следующем примере условие буквально звучит так: «пока не завершилась загрузка (выполнять блок кода)».
Это может привести к путанице, потому что не очень естественно думать одновременно позитивно и негативно. Вместо этого, мы могли бы использовать цикл until, который по сути является негативной формой цикла while.
В этой пересмотренной версии, условие until выглядит более натурально: «пока завершается загрузка (выполнять блок кода)». Это может помочь сделать ваш код более читабельным и чистым.
Примечание переводчика:
На русском не совсем понятно, что хотела сказать автор. Я не хотел далеко отходить от оригинала, чтобы сильно не переврать смысл. Но от себя хочу добавить, что в целом стоит избегать логического «не» в условиях, так как оно, зачастую, не воспринимается при попытке прочитать код, что может привести к трудностям с отладкой логических выражений.
Совет №3: Используйте loop do вместо while(true)
Цикл loop do предлагает, во многих случаях, более чистый синтаксис, чем условие while(true). Давайте сравним две версии кода:
В общем, цикл loop do предлагает более чистый и лучший синтаксис при работе с внешними итераторами. Ещё одно преимущество заключается в том, что цикл loop do позволяет вам итерировать две коллекции одновременно, что приводит к чистому и лёгкому коду на Руби.
Примечание переводчика:
Нужно также отметить, что цикл loop гораздо медленнее цикла while:
Приблизительно в 3 раза. Как и у цикла for, между прочим. Но это не означает, что нужно полностью отказываться от цикла loop. Просто нужно понимать его недостатки и пользоваться преимуществами, наподобие того, что было приведено.
Совет №4: Используйте «или-присваивание» ||= в ваших методах
«Или-присваивание» — хороший способ писать лаконичный код на Руби. Оно эквивалентно следующему коду: a || a = b
a ||= b работает как оператор условного присваивания, поэтому если a не определено или ложно, то в него запишется результат из b.
Этот оператор отлично подходит для создания методов в ваших классах, особенно для вычислений.
Совет №5: Исправляйте сборщик мусора (Garbage Collector)
Сборщик мусора Ruby (Garbage Collector — GC) известен своей медленной работой, особенно в версиях до 2.1. Алгоритм сборщика мусора Ruby — «маркируй и очищай» (самый медленный для сборщиков мусора), и он должен останавливать приложение во время процессов сборки мусора.
Чтобы исправить это, мы можем включить настраиваемые расширения GC. Это очень поможет увеличить скорость при масштабировании вашего приложения Ruby.
Вы можете настроить переменные основываясь на вашей версии Руби. Также, на GitHub можно отыскать много чего полезного, если вы не хотите писать этот код сами. Вот три примера:
- RUBY_GC_HEAP_INIT_SLOTS: начальные слоты распределения
- RUBY_GC_HEAP_FREE_SLOTS: подготовить хотя бы указанное количество слотов после сборки мусора и выделить слоты, если их недостаточно
- RUBY_GC_HEAP_GROWTH_MAX_SLOTS: ограничить скорость выделения до этого количества слотов
Примечание переводчика:
Здесь она как-то совсем по верхам прошлась. Лично мне ничего не понятно, поэтому будет ещё статья или серия статей на тему оптимизации Garbage Collector.
Совет №6: Используйте Hash[…] для создания хэша из списка значений
Вы можете легко создавать хэши из списков на Руби, используя Hash[…]. Например:
Представьте, мы собрали данные в табличном формате. Они организованы в виде массива с названиями столбцов, и массива массивов представляющих значения в строках:
Ключами для наших окончательных хэшей будет массив столбцов, который содержит имена наших столбцов, а табличные данные — это наш массив массивов, содержащий данные строк. Мы хотим создать массив хэшей, чтобы в них каждый ключ был именем столбца, а строка — значением. Можно сделать это двумя способами:
Совет №7: Избегайте применять в циклах медленно работающие методы
При работе с циклами в Ruby важна скорость. Поэтому нам нужно избегать более медленных методов и находить альтернативы, которые помогут сделать работу нашей программы более производительной.
Например, известно, что метод Date#parse известен своей низкой производительностью, так как он ожидает получить дату сразу в нескольких форматах и проверяет каждый из них. Вместо него, лучше будет прямо указать ожидаемый формат даты используя метод Date#strptime — он отработает в несколько раз быстрее. Предположим, что мы хотим работать с датой в формате «дд/мм/гггг»:
С точки зрения проверки типов, использование методов Object#class, Object#kind_of? и Object#is_a? также может привести к снижению производительности, если применять их в цикле. Вместо этого лучше сохранять в переменную результат вызова такого метода вне цикла, а в цикле использовать переменную, если такое возможно.
Совет №8: Следуйте лучшим примерам кода на Руби
Такие примеры работы с Ruby помогают нам писать лаконичный код, с которым легко работать в дальнейшем. Давайте посмотрим на некоторые из них, которые вы можете начинать использовать уже сегодня:
- Когда это возможно, используйте гемы, вместо того, чтобы писать код с нуля для получения более оптимизированного кода
- Избегайте использования цикла for — вместо этого, старайтесь применять метод each с блоком
- Используйте тернарный оператор ( ? : ) для написания более короткого кода
- Вместо длинных цепочек if—elsif—end, используйте case—when и unless/until/while
- Используйте оператор «звёздочка» * для группировки аргументов метода в массив, когда ваши методы имеют нефиксированное количество аргументов (то же самое можно сказать и про ** для группировки аргументов метода в хэш — прим.пер.)
- Для именования ключей в хэше используйте символы (Symbol) вместо строк (String) (использование символов повышает производительность вашего кода — прим.пер.)
- Избегайте использования комментариев, если в них нет необходимости. В идеале ваш код должен быть достаточно понятным сам по себе, чтобы не нуждаться в комментариях
- Используйте двойной восклицательный знак !!, чтобы создавать методы, которые определяют, существует ли полученное значение
- Используйте APM (??? — прим.пер.) во время разработки. Это поможет вам сразу узнать, когда что-то новое в вашем коде вызвало падение производительности
- При создании методов помните два простых правила: метод должен делать только одну вещь, и ему нужно четкое имя, отражающее эту единственную цель
Что ещё стоит изучить
Эти советы и рекомендации помогут вам писать более читаемый и понятный код Ruby для повышения производительности. Ruby — отличный язык с множеством интересных синтаксических приемов. Чтобы максимально использовать этот язык, вы должны изучить всё, что можете о нем.
Вот на что ещё стоит обратить внимание работая с Руби:
- Методы параллелизма и многопоточности
- Отслеживание запущенных процессов
- Когда использовать nil
- Преобразование базы чисел
Спасибо, что дочитали до конца!
#ruby #tricks #tips #best practice #руби #советы #хитрости #рекомендации