Коротко о том, почему Rust лучше C/C++

52ffb7e7a919b43fbf7aa5a15970aaff.png

Это будет статья-рассуждение о том, почему Rust лучше C/C++. Тут будут затронуты не столько сравнение производительности, сколько сравнение удобства инфраструктуры языка, его темпы развития и актуальность.

Толчком к её написанию были многочисленные «горячие» споры в комментариях под статьями Хабра о том, почему Rust или C/C++ лучше. Я же попробую занять объективно-нейтральную позицию в этом споре, поэтому о минусах тоже будет речь.

Унифицированность

Давайте для начала обсудим заметное количество существующих компиляторов C/C++. Это преимущество или недостаток? Многие сторонники C/C++ уверенно говорят о том, что это огромный плюс. Но действительно ли это так? Давайте погрузимся в эту тему и рассмотрим ее более детально.

Спросите у любого опытного программиста C/C++, и он подтвердит, что попытка скомпилировать программу, написанную на C/C++, с использованием MinGW или Clang без каких-либо изменений в коде, скорее всего, не увенчается успехом. Причина этого кроется в том, что каждый из этих инструментов использует свои собственные реализации стандартных функций, операторов, библиотек и так далее.

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

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

Инфраструктура

Никто в здравом уме не будет отрицать преимущества полноценного тулчейна с возможностью расширения, менеджера пакетов, тестирования и т. д., которые предлагает Rust, по сравнению с C/C++. Это преимущества, которые определенно улучшают процесс разработки программного обеспечения и предоставляют разработчикам более современные инструменты для работы.

Конечно, кто-то может сказать, что у C/C++ тоже есть свои инструменты для сборки, менеджеры пакетов, но, к сожалению, они не стали популярными из-за тех или иных причин, включая сложность использования и отсутствие единого стандарта.

Из этого следует, что одной из ключевых проблем C/C++ является работа с библиотеками и их сборка. Для сборки одной библиотеки может потребоваться загрузка и установка большого количества дополнительного программного обеспечения, что может быть сложно и затратно по времени, а для другой библиотеки — уже другого. Это не только увеличивает сложность процесса, но и может привести к проблемам совместимости.

В Rust есть официальный менеджер пакетов Cargo, который позволяет делать практически все: от создания проекта до его сборки, запуска тестов и деплоя. Это делает процесс разработки более простым и понятным. Дополнительным преимуществом является возможность расширения функциональности через так называемые крейты.

В контексте Rust, крейт — это любая кодовая единица: программа или библиотека, содержащая файл проекта Cargo.toml.

Это означает, что разработчики могут легко использовать и переиспользовать код, что способствует повышению эффективности и сокращению времени разработки.

Небольшим недостатком, а не полноценным минусом, может стать официальный репозиторий крейтов crates.io. Политика фонда вызывает у сообщества некоторые опасения насчет того, не превратится ли репозиторий в очередной npm. Это вопрос, который требует внимания, и он не должен быть проигнорирован, но на данный момент это не является серьезной проблемой.

Строгий компилятор и безопасность Rust

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

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

В 2018 году было доказано, что система типов Rust, механизмы заимствования, владения, времён жизни и многопоточности корректны. Также было установлено, что если мы используем семантически правильный код из библиотек внутри unsafe и смешаем это с синтаксически правильным safe кодом, мы получим семантически правильный код, который не позволяет стрелять по памяти или делать гонки данных.

Источник: C++ быстрее и безопаснее Rust, Yandex сделала замеры.

Вдобавок, стоит отметить, что часто упоминают о том, что такие концепции, как result pattern и другие, далеко не новы для Rust, и что подобные идеи были реализованы и в других языках программирования. Это, безусловно, так. Например, в C++ есть умные указатели, optional и множество других элементов. Однако, стоит учесть, что все эти функции были введены в C++ уже после его создания, поэтому они реализованы на уровне библиотек и их использование не является обязательным. Это значит, что разработчики могут выбирать, использовать их или нет. В отличие от этого, Rust изначально включил в себя лучшие практики и идеи из мира программирования и использует их на уровне языка, делая их использование неотъемлемой частью процесса написания более безопасного кода.

Как говаривал один мудрый человек: если человек хочет написать небезопасный код, то ничто не сможет его остановить. Это может быть истиной для любого языка программирования, но Rust делает все возможное, чтобы сделать процесс написания безопасного кода как можно проще.

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

Производительность является одним из ключевых факторов при выборе языка программирования, и вокруг сравнения производительности Rust и других языков уже написано множество статей. Большинство из них фокусируются именно на сравнении скорости выполнения одной и той же программы на этих разных языках. Есть такие работы, которые выставляют Rust в положительном ключе, а есть и те, которые предпочитают другие языки.

Однако, стоит отметить, что сравнение производительности двух языков программирования — это задача довольно сложная, даже если они используют один и тот же бэкенд*. Сложность заключается в том, что разные компиляторы могут применять разные стратегии оптимизации и концепции, которые в свою очередь могут значительно влиять на производительность. Даже абстракции, используемые в языке, могут иметь значительное влияние на это**.

* Компилятор использует в качестве бэкенда LLVM, как и Clang.

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

В связи с этим, в данной статье не будет результатов каких-либо бенчмарков, и просто сойдёмся на том, что эти языки равны по производительности. Если вам интересны более точные данные, рекомендую искать специализированные материалы на эту тему. Также вы можете обратить внимание на портал TechEmpower, где авторы регулярно проводят бенчмарки различных веб-фреймворков.

С другой стороны, важным аспектом в области программирования, особенно в контексте современных технологий, является производительность написания и отладки кода. Это непрерывно акцентируется, поскольку время — это ресурс, которого у нас никогда не хватает. С учетом всего выше сказанного, можно утверждать, что написание кода на Rust является не только быстрым, но и эффективным процессом.

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

Кроме того, установка расширений Cargo, позволяющих создавать шаблоны проектов, может делать процесс еще более упрощенным. Это дает программистам возможность быстро настраивать новые проекты и экономить время на стандартных задачах, ускоряя процесс разработки и повышая его эффективность.

Неопределённое поведение C/C++

В языках программирования C/C++ существует обширный спектр случаев неопределённого поведения, которые могут стать причиной серьёзных проблем и нестабильности в рамках написанного кода. Это широко вариативно включает в себя все возможные аспекты, начиная от непредсказуемых результатов выполнения функций и заканчивая возможностью выполнения произвольного кода. Это может привести к неконтролируемым и непредсказуемым результатам, которые в свою очередь могут вызвать критические ошибки в работе программы, нарушить её стабильность и даже привести к потенциальным угрозам безопасности.

С другой стороны, в языке программирования Rust, была применена другая концепция управления ошибками и неопределенным поведением. Компилятор этого языка применяет строгий контроль над всеми возможными случаями неопределённого поведения. Это означает, что каждый потенциальный случай неопределенного поведения будет проверен и обработан во время компиляции, предотвращая возможность его проявления во время выполнения программы.

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

Итого

Если встаёт вопрос, какой язык выбрать в качестве стартового? Начинающим программистам часто рекомендуют начать с C++, поскольку большинство современных языков программирования используют парадигму объектно-ориентированного программирования (ООП). Такой подход упрощает понимание более высокоуровневых и абстрактных концепций, которые присутствуют в других языках программирования.

В то же время, стоит упомянуть язык программирования Rust, который придерживается функционального программирования (ФП) и использует уникальную систему владения. Эти концепции используются редко в других языках, что может затруднить переход на другой язык программирования после изучения Rust.

Если рассмотреть ситуацию с точки зрения рынка труда, то Rust крайне мало востребован на территории России. В сравнении с этим, навыки работы с C/C++ гораздо более ценятся работодателями и востребованы на рынке.

Поэтому, несмотря на то что Rust является более современным и удобным языком по сравнению с C/C++, его преимущества угасают из-за недостатка спроса на рынке. Rust предлагает большое количество инновационных функций и преимуществ, но они становятся менее значимыми, если учесть низкую востребованность этого языка в реальном мире.

В итоге, выбор между C++ и Rust в качестве первого языка программирования будет зависеть от множества факторов, включая личные предпочтения, цели обучения и перспективы трудоустройства. Независимо от выбора, важно помнить, что основные концепции программирования остаются неизменными, и навыки, приобретенные при изучении одного языка, часто могут быть применены и в других контекстах.

Habrahabr.ru прочитано 14421 раз