Оптимизация C++: строки или перечислимый тип? | OTUS
⚡ Подписка на курсы OTUS!
Интенсивная прокачка навыков для IT-специалистов!
Подробнее

Курсы

Программирование
iOS Developer. Professional Kotlin Backend Developer Flutter Mobile Developer Symfony Framework C++ Developer. Basic Unity Game Developer. Basic Java Developer. Professional
-35%
Highload Architect Unity Game Developer. Professional React.js Developer Специализация Java-разработчик
-25%
Алгоритмы и структуры данных
-16%
Scala-разработчик C# Developer. Professional
-23%
Разработчик голосовых ассистентов и чат-ботов Team Lead Архитектура и шаблоны проектирования NoSQL Web-разработчик на Python Golang Developer. Professional PostgreSQL Vue.js разработчик Супер-практикум по использованию и настройке GIT Разработчик IoT Подготовка к сертификации Oracle Java Programmer (OCAJP) Программист С HTML/CSS
Инфраструктура
Инфраструктурная платформа на основе Kubernetes Microservice Architecture Базы данных Highload Architect Reverse-Engineering. Professional
-8%
Network engineer. Basic Administrator Linux.Basic MongoDB Infrastructure as a code MS SQL Server Developer Cloud Solution Architecture Мониторинг и логирование: Zabbix, Prometheus, ELK Супер-практикум по использованию и настройке GIT Разработчик IoT Экcпресс-курс «ELK» Супер-интенсив "Tarantool" Экспресс-курс «CI/CD или Непрерывная поставка с Docker и Kubernetes» Экспресс-курс «Введение в непрерывную поставку на базе Docker»
Корпоративные курсы
Безопасность веб-приложений Экосистема Hadoop, Spark, Hive Пентест. Практика тестирования на проникновение Node.js Developer Java QA Engineer. Basic
-18%
Reverse-Engineering. Professional
-8%
DevOps практики и инструменты NoSQL Reverse-Engineering. Basic Cloud Solution Architecture Внедрение и работа в DevSecOps Супер-практикум по работе с протоколом BGP Game QA Engineer Супер - интенсив по Kubernetes Дизайн сетей ЦОД Экспресс-курс «IaC Ansible» Экспресс-курс по управлению миграциями (DBVC) Экспресс-курс "Версионирование и командная работа с помощью Git" Основы Windows Server
Специализации Курсы в разработке Подготовительные курсы Подписка
+7 499 938-92-02

Оптимизация C++: строки или перечислимый тип?

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

Сравнения и опечатки

Строки могут содержать практически любые последовательности символов, в том числе и бессмысленные. И если где-нибудь в сравнении допустили опечатку, найти её станет непростой задачей. А вот перечислимые типы, напротив, являются идентификаторами, поэтому компилятор пожалуется на несоответствие.

В качестве примера давайте рассмотрим небольшую функцию:

void printMessage(string const& msg, string const& messageType) {
  if (messageType == "waring") {
    std::cout << "WARN: "; //!
  }
  //...
}

Помеченная строка в нашем примере никогда не будет достигнута, так как messageType никогда не станет равен "waring". Это опечатка, которая сделана намеренно. Но если бы она была случайной, пришлось бы тратить время на отладку. А если бы мы использовали перечислимый тип, IDE и компилятор указали бы на ошибку сразу.

Соответствие типов

Вызовем предыдущую функцию:

printMessage("error", "Something bad happened!");

Ой… Мы только что пытались напечатать сообщение типа "Something bad happened!" с текстом "error". Но если бы тип сообщения был перечислимым, этой проблемы бы не возникло.

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

Switch/case

В языке программирования C++ мы не можем использовать строки в условном операторе switch. В результате, вместо этого, нам приходится нагромождать if/else. А вот enum’ы — можем! Вдобавок к этому, мы сможем получать предупреждения компилятора либо статического анализатора, если забудем про перечислимый тип.

Производительность

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

Стоит отметить, что сравнения перечислимых типов, как правило, быстрее, чем сравнения строк. При этом размер перечислимого типа равен размеру целого типа, а строки бывают весьма большими. Также оператор switch можно транслировать в jump-таблицы, что бывает эффективнее if/else.

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

Вывод прост: если у вас есть фиксированный набор строк, применяемый в качестве входных либо выходных данных, его однозначно надо конвертировать в enum.

По материалам статьи «Strings vs. Enumerators».

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

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

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

Автор
0 комментариев
Для комментирования необходимо авторизоваться