Не мешайте лодке плыть: об идеальном коде на C++ | OTUS
🔥 BLACK FRIDAY!
Максимальная скидка -25% на всё. Успейте начать обучение по самой выгодной цене.
Выбрать курс

Курсы

Программирование
iOS Developer. Basic
-25%
Python Developer. Professional
-25%
Разработчик на Spring Framework
-25%
Golang Developer. Professional
-25%
Python Developer. Basic
-25%
iOS Developer. Professional
-25%
Highload Architect
-25%
JavaScript Developer. Basic
-25%
Kotlin Backend Developer
-25%
JavaScript Developer. Professional
-25%
Android Developer. Basic
-25%
Unity Game Developer. Basic
-25%
Разработчик C#
-25%
Программист С Web-разработчик на Python Алгоритмы и структуры данных Framework Laravel PostgreSQL Reverse-Engineering. Professional CI/CD Vue.js разработчик VOIP инженер Программист 1С Flutter Mobile Developer Супер - интенсив по Kubernetes Symfony Framework Advanced Fullstack JavaScript developer Супер-интенсив "Azure для разработчиков"
Инфраструктура
Мониторинг и логирование: Zabbix, Prometheus, ELK
-25%
DevOps практики и инструменты
-25%
Архитектор сетей
-25%
Инфраструктурная платформа на основе Kubernetes
-25%
Супер-интенсив «IaC Ansible»
-16%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-25%
Супер-интенсив "SQL для анализа данных"
-16%
Базы данных Сетевой инженер AWS для разработчиков Cloud Solution Architecture Разработчик голосовых ассистентов и чат-ботов Внедрение и работа в DevSecOps Администратор Linux. Виртуализация и кластеризация Нереляционные базы данных Супер-практикум по использованию и настройке GIT IoT-разработчик Супер-интенсив «ELK»
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Не мешайте лодке плыть: об идеальном коде на C++

Cplus_Deep_14.3_site-4868-be09ae.png

Есть такая забава — плавать на лодках по прудикам и речкам. Мореманы хмыкнут и скажут, что не «плавают», а «ходят». Мы ИТ-шники. Нам можно и не такое.

Бывает так, что на борту оказывается активный новичок, результативность которого несопоставима с мощностью реки. В таких случаях можно услышать, - «Не мешай лодке плыть самой!». Действительно, деятельность такого гребца наносит больше вреда, нежели пользы.

Теперь две новости

Плохая, пора признаться себе честно в том, что тягаться с современными компиляторами и их средствами оптимизации становится всё сложнее и сложнее. На самом деле я уверен, что в большинстве случаев это уже невозможно, но буду себя тешить мыслью, что просто сложнее.

Есть и хорошая новость, в отличие от бурной реки, на которой у нас просто нет времени, в отношениях с компилятором у нас есть возможность вдумчиво оттачивать нашу технику.

Есть избитая мысль о том, что человеку лучше оставить оптимизацию алгоритмическую, то есть найти все «O» и стремиться нагнуть их в горизонт. Низкоуровневую оптимизацию лучше оставить компилятору.

Но в процессе работы, особенно в настроении «пишу сразу идеальный код», хочется нет-нет да и помочь кодогенератору сделать идеальный код тоже.

И вот опять, в который раз, я свидетель такой инициативы. Инициатива «сделать всё лучше» прекрасна, особенно в сочетании с хоть какими-то доказательствами её эффективности.

Итак, код сильно упрощён и очищен от смысла, оставлена лишь ключевая конструкция.

#include <iostream>

void foo(int num) {
  if (num == 0)
    std::cout << "zero" << std::endl;
  else if (num == 1)
    std::cout << "one" << std::endl;
  else if (num == 2)
    std::cout << "two" << std::endl;
  else if (num == 3)
    std::cout << "three" << std::endl;
}

Теперь, когда вы посмотрели этот код, я ещё раз повторю, что оставлена лишь ключевая конструкция.

Итак, где хочется помочь: изменить на switch, где же ещё. Получаем:

#include <iostream>

void foo(int num) {
  switch (num) {
  case 0:
    std::cout << "zero" << std::endl;
    break;
  case 1:
    std::cout << "one" << std::endl;
    break;
  case 2:
    std::cout << "two" << std::endl;
    break;
  case 3:
    std::cout << "three" << std::endl;
    break;
  }
}

Казалось бы совсем не похоже: переменную читаем один раз и выражаем своё намерение более явно. Прежде чем делать такой вывод, крайне полезно посмотреть получившийся код. Для этого нам может понадобится либо набор специальных ключей для компилятора, либо, что гораздо проще и нагляднее, использовать online-сервис.

Что мы увидим в первом и втором случаях?

Что компилятор построил практический идентичный код, который даже скорее ближе в первому варианту с if. Не идентичный, но очень похожий. Казалось бы, вот он ценный опыт, который следует бросить в копилку своих навыков.

Торопиться не будем, ведь если бы наш switch был хотя бы на один case длиннее, то код получился бы совершенно иной. Он был бы похож на таблицу указателей, которая индексируется нашим значением num. Обратите внимание, если бы case-ы были в более крупных диапазонах, например, от 1000 до 1020, то это бы не помешало компилятору построить таблицу переходов, просто перед индексацией будет вычтено значение 1000.

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

Это лишний раз свидетельствует о том, что мы вполне можем сосредоточиться на написании кода в таком виде, в котором он больше будет нравиться нам самим. Не забывая, конечно же, периодически проверять что на самом деле генерирует компилятор, чтобы не перейти ту черту, когда наш «идеальный и красивый» код начинает превращаться в какую-то кашу, поскольку даже компилятор не смог понять, что же именно мы планировали сделать.

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

#include <iostream>

void foo(int num) {
  const char* p;
  if (num == 0)
    p = "zero";
  else if (num == 1)
    p = "one";
  else if (num == 2)
    p = "two";
  else if (num == 3)
    p = "three";

  std::cout << p << std::endl;
}

Фактически наша строка была вынесена в отдельную переменную, а её печать выполнялась в конце.

Желаю всем интересных экспериментов и открытий!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
🎁 Максимальная скидка!
Черная пятница уже в OTUS! Скидка -25% на всё!