27.02.2024

Выпуск языка программирования Rust 1.75 и unikernel Hermit 0.6.7

Опубликован релиз языка программирования общего назначения Rust 1.75, основанного проектом Mozilla, но ныне развиваемого под покровительством независимой некоммерческой организации Rust Foundation. Язык сфокусирован на безопасной работе с памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime (runtime сводится к базовой инициализации и сопровождению стандартной библиотеки).

Методы работы с памятью в Rust избавляют разработчика от ошибок при манипулировании указателями и защищают от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo. Для размещения библиотек поддерживается репозиторий crates.io.

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

Основные новшества:

  • Добавлена возможность использования «async fn» и нотации «->impl Trait» в приватных типажах. Например, используя «->impl Trait» можно написать метод типажа, возвращающий итератор:
     trait Container { fn items(&self) -> impl Iterator‹Item = Widget›; } impl Container for MyContainer { fn items(&self) -› impl Iterator‹Item = Widget› { self.items.iter().cloned() } }
    

    Также можно создавать типажи, использующие «async fn»:

     trait HttpService { async fn fetch(&self, url: Url) -› HtmlBody; // будет развёрнуто в: // fn fetch(&self, url: Url) -> impl Future‹Output = HtmlBody›; }
    
  • Добавлен API для расчёта байтовых смещений относительно указателей. При работе с голыми указателями («*const T» и «*mut T») могут потребоваться операции добавления смещения к указателю. Ранее для этого можно было использовать конструкцию вида «‹*const T›::add(1)», добавляющую число байтов, соответствующее размеру «size_of::()». Новый API упрощает данную операцию и даёт возможность манипулировать смещениями в байтах без предварительного приведения типов к «*const u8» или «*mut u8».
  • Продолжена работа по увеличению производительности компилятора rustc. В состав добавлен оптимизатор BOLT, работающий на стадии после завершения компоновки и использующий сведения из заранее подготовленного профиля выполнения. Применение BOLT позволяет ускорить выполнение компилятора примерно на 2% за счёт изменения раскладки кода библиотеки librustc_driver.so для более эффективного использования процессорного кэша.

    Включена сборка компилятора rustc с опцией «-Ccodegen-units=1», позволяющей повысить качество оптимизации в LLVM. Проведённые тесты показывают увеличение производительности в случае со сборки «-Ccodegen-units=1» примерно на 1.5%. Добавленные оптимизации по умолчанию включаются только для платформы x86_64-unknown-linux-gnu.

    Ранее указанные оптимизации были опробованы компанией Google для сокращения времени сборки компонентов платформы Android, написанных на языке Rust. Применение «-C codegen-units=1» при сборке Android позволило снизить размер инструментария на 5.5% и увеличить его производительность на 1.8%, при этом время сборки самого инструментария увеличилось почти в два раза.

    Включение сборки мусора во время компоновки («—gc-sections») дало возможность довести прирост производительности до 1.9%, включение оптимизации на этапе связывания (LTO) — до 7.7%, а оптимизаций на основе профиля выполнения кода (PGO) — до 19.8%. В финале были применены оптимизации при помощи утилиты BOLT, которые позволили довести прирост скорости сборки до 24.7%, но размер инструментария при этом вырос на 10.9%.

  • В разряд стабильных переведена новая порция API, в том числе стабилизированы методы и реализации типажей:
  • Признак «const», определяющий возможность использования в любом контексте вместо констант, применён в функциях:
  • Реализован третий уровень поддержки для платформы csky-unknown-linux-gnuabiv2hf, i586-unknown-netbsd и mipsel-unknown-netbsd. Третий уровень подразумевает базовую поддержку, но без автоматизированного тестирования, публикации официальных сборок и проверки возможности сборки кода.

Дополнительно можно отметить новую версию проекта Hermit, развивающего специализированное ядро (unikernel), написанное на языке Rust, предоставляющее инструментарий для сборки самодостаточных приложений, способных работать поверх гипервизора или голого оборудования без дополнительных прослоек и без операционной системы. При сборке приложение статически связывается с библиотекой, которая самостоятельно реализует всю необходимую функциональность, не привязываясь к ядру ОС и системным библиотекам. Код проекта распространяется под лицензиями Apache 2.0 и MIT. Поддерживается сборка для обособленного выполнения приложений, написанных на языках Rust, Go, Fortran, C и C++. Также проектом развивается собственный загрузчик, позволяющий запускать Hermit при помощи QEMU и KVM.

Источник: https://www.opennet.ru/opennews/art.shtml?num=60364 Источник.