#prog #rust #rustreleasenotes
Вышла версия Rust 1.80.0! Как всегда, тут только избранные моменты, а остальное в детальных заметках о релизе.
(rust playground всё ещё не обновился, так что примеры кода проверяйте локально или на nightly)
▪️В паттернах теперь можно использовать диапазоны с исключающей верхней границей. Пример из блога:
▪️Важное изменение для unsafe кода: теперь на произвольных выровненных указателях разрешены чтение и запись значений типов нулевого размера, включая null. Также на всех указателях (и null) разрешены смещения на 0, и offset_from всегда разрешён для указателей с одинаковым адресом из одной аллокации.
▪️В релизе Rust 1.75.0 были даны гарантии на раскладку в памяти
Например,
⚠️ std теперь может уронить программу в большем числе случаев. Смотри ниже:
🔸Помните, в Rust 1.63 добавили типы для IO safety? Так вот, в отладочной сборке (читай, при
🔸Также в отладочной сборке
🔸Тип fmt::Error должен использоваться лишь для индикации того, что запись в нижележащий приёмник информации более невозможна, но не для передачи ошибок в самом процессе форматирования как таковом. В частности, в силу того, что
🔸PathBuf::set_extension теперь паникует, если новое расширение содержит разделитель пути файловой системы.
▪️Добавлены типы LazyCell и LazyLock, которыеимитируют автора этого канала позволяют хранить значение, вычисляемое по требованию при помощи предоставленной при создании функции. Значит ли это, что теперь можно выкинуть once_cell? Отнюдь. У этих типов не стабилизированы методы для получения содержимого без форсирования их вычисления, и по непонятным причинам оба не дают никакого способа (даже нестабильного) получить мутабельный доступ к содержимому.
Более того, получения значения из
Вышла версия Rust 1.80.0! Как всегда, тут только избранные моменты, а остальное в детальных заметках о релизе.
(rust playground всё ещё не обновился, так что примеры кода проверяйте локально или на nightly)
▪️В паттернах теперь можно использовать диапазоны с исключающей верхней границей. Пример из блога:
fn size_prefix(n: u32) -> &'static str {
const K: u32 = 10u32.pow(3);
const M: u32 = 10u32.pow(6);
const G: u32 = 10u32.pow(9);
match n {
..K => "",
K..M => "k",
M..G => "M",
G.. => "G",
}
}▪️Важное изменение для unsafe кода: теперь на произвольных выровненных указателях разрешены чтение и запись значений типов нулевого размера, включая null. Также на всех указателях (и null) разрешены смещения на 0, и offset_from всегда разрешён для указателей с одинаковым адресом из одной аллокации.
▪️В релизе Rust 1.75.0 были даны гарантии на раскладку в памяти
Option для некоторых типов т. н. "null pointer optimization" (название не вполне верное, поскольку не только у ссылок есть ниша на битовом паттерне из одних нулевых битов). В этом релизе схожие гарантии дали и для раскладки Result. Именно, Result имеет такое же представление в памяти, как и аналогичный Option с одним из типовых параметров, если для этого параметра есть гарантии "null pointer optimization" при оборачивании в Option, а второй типовый параметр является типом нулевого размера с выравниванием 1, без полей и без атрибута #[non_exhaustive].Например,
Result<NonZero<i32>, ()> и Result<(), NonZero<i32>> теперь имеют такие же размер, выравнивание и гарантии ABI, как и Option<NonZero<i32>>.⚠️ std теперь может уронить программу в большем числе случаев. Смотри ниже:
🔸Помните, в Rust 1.63 добавили типы для IO safety? Так вот, в отладочной сборке (читай, при
#[cfg(debug_assertions)]) дроп OwnedFd теперь прерывает работу процесса, если соответствующий файловый дескриптор уже закрыт.🔸Также в отладочной сборке
unchecked_* арифметические методы паникуют при нарушении предусловий их безопасного использования.🔸Тип fmt::Error должен использоваться лишь для индикации того, что запись в нижележащий приёмник информации более невозможна, но не для передачи ошибок в самом процессе форматирования как таковом. В частности, в силу того, что
String может расширяться по мере нужды, форматирование в String считается операцией, которая не может вернуть ошибку. Для того, чтобы усилить соблюдение этого контракта, теперь форматирование в новый String паникует при ошибке из реализации одного из fmt методов, а форматирование в IO-ресурсы (стандартный вывод, например) паникует, если ошибку вернул метод форматирования, но не запись данных в IO-ресурс.🔸PathBuf::set_extension теперь паникует, если новое расширение содержит разделитель пути файловой системы.
▪️Добавлены типы LazyCell и LazyLock, которые
Более того, получения значения из
LazyLock блокирует вызывающий поток, если значение ещё не вычислено или в процессе вычисления. Как правило, это то, что нужно для корректной логики, но в некоторых случаях можно или даже нужно позволить сразу нескольким потокам вычислять значение одновременно и установить в итоге то, которое было у самого первого потока, завершившего работу (например, время старта первого рабочего потока в тредпуле). Для таких юзкейсов в once_cell есть типы из модуля race. Помимо логического отличия, эти типы за счёт отказа от блокировки потоков могут быть использованы на платформах без операционной системы.👍8😁1
▪️Несколько багфиксов:
🔸Греческая буква Σ (сигма) имеет две формы нижнего регистра: ς при использовании в конце слова и σ во всех остальных позициях.
🔸Функции
🔸Компилятор теперь предупреждает, когда во вложенном определении используется конструктор
🔸В паттернах теперь нельзя использовать функциональные указатели и сырые указатели, полученные не путём каста из числового значения.
🔸Теперь нельзя преобразовывать в трейт-объекты трейты, у которых есть ограничения вида
🔸Для ReentrantLockGuard (внутренней реализации
▪️Некоторые стабилизированные API:
🔸
🔸Option::take_if — как
🔸Множество методов на
🔸Методы split_at{, _mut}_checked на слайсах и на
🔸Методы trim{, _start, _end}_ascii на байтовых слайсах и на
🔸Метод into_flattened для преобразования
▪️
🔸Греческая буква Σ (сигма) имеет две формы нижнего регистра: ς при использовании в конце слова и σ во всех остальных позициях.
str::to_lowercase теперь корректно обрабатывает этот граничный случай.🔸Функции
env::set_var и env::remove_var теперь являются unsafe функциями в Edition 2024 (как и должны быть, но эта смена невозможна в более старых редакциях из-за гарантий обратной совместимости).🔸Компилятор теперь предупреждает, когда во вложенном определении используется конструктор
Self, относящийся к определению выше в области видимости. В будущем это сделают ошибкой компиляции.🔸В паттернах теперь нельзя использовать функциональные указатели и сырые указатели, полученные не путём каста из числового значения.
🔸Теперь нельзя преобразовывать в трейт-объекты трейты, у которых есть ограничения вида
Self: Trait на отдельных определениях внутри (не на определении трейта целиком). Ранее это было разрешено и позволяло написать код, который сегфолтился в рантайме при попытке вызвать из vtable функцию, которой там не было :/ Закрывает issue от аж мая 2018 года.🔸Для ReentrantLockGuard (внутренней реализации
StdinLock и StderrLock) исправили реализацию Sync. Как следствие, StdinLock и StderrLock более не реализуют Sync.▪️Некоторые стабилизированные API:
🔸
size_of, size_of_val, align_of и align_of_val. Да, это не новые API, но теперь они включены в прелюдию.🔸Option::take_if — как
Option::take, но с предикатом (который может и модифицировать содержимое).🔸Множество методов на
NonNull, которые были ранее доступны на сырых указателях (слишком много, чтобы перечислять здесь).🔸Методы split_at{, _mut}_checked на слайсах и на
str — как split_at, но возвращает None при выходе за границу. Почему только сейчас?🔸Методы trim{, _start, _end}_ascii на байтовых слайсах и на
str.🔸Метод into_flattened для преобразования
Vec<[T; N]> -> Vec<T> и аналогичные методы as_flattened{, _mut} на слайсах.▪️
check-cfg теперь всегда работает — иными словами, компилятор ловит опечатки в атрибутах #[cfg]👍4🥰2
#prog #article
RocksDB: Not A Good Choice for a High-Performance Streaming Platform
TL;DR:
- Катастрофическое падение производительности при использовании из нескольких потоков;
- Создание и удаление column families является квадратичными от числа column families операциями. В проде это не было проблемой, но в тестах (со значительным использованием property-based testing) новые colum family создавались и удалялись для каждого теста. Общее время прогона тестов из-за этого увеличилось с двух минут до тридцати.
- Невозможность задействовать rkyv. rkyv — библиотека для Rust, которая позволяет переводить типы в их "архивные" версии в виде байтовых слайсов, из которых можно восстановить исходные данные с минимальными вычислительными затратами и без копирования данных. Для корректной работы rkyv накладывает некоторые ограничения на выравнивание "архивных" данных, но эти ограничения невозможно зафорсить в RocksDB — все значения имеют единичное выравнивание.
- Переусложнённая настройка — настолько, что для нахождения оптимальных конфигураций сделали отдельную машобуч-модель — которая всё равно не даёт большой возможности скорректировать настройки в сторону производительности.
RocksDB: Not A Good Choice for a High-Performance Streaming Platform
TL;DR:
- Катастрофическое падение производительности при использовании из нескольких потоков;
- Создание и удаление column families является квадратичными от числа column families операциями. В проде это не было проблемой, но в тестах (со значительным использованием property-based testing) новые colum family создавались и удалялись для каждого теста. Общее время прогона тестов из-за этого увеличилось с двух минут до тридцати.
- Невозможность задействовать rkyv. rkyv — библиотека для Rust, которая позволяет переводить типы в их "архивные" версии в виде байтовых слайсов, из которых можно восстановить исходные данные с минимальными вычислительными затратами и без копирования данных. Для корректной работы rkyv накладывает некоторые ограничения на выравнивание "архивных" данных, но эти ограничения невозможно зафорсить в RocksDB — все значения имеют единичное выравнивание.
- Переусложнённая настройка — настолько, что для нахождения оптимальных конфигураций сделали отдельную машобуч-модель — которая всё равно не даёт большой возможности скорректировать настройки в сторону производительности.
Feldera
RocksDB: Not A Good Choice for a High-Performance Streaming Platform
We go over our findings when trying to use RocksDB as our storage engine
🤔5😁1😢1
#prog #rust #article
Лодочник пишет о Pin.
Именно, в первой статье — Pin — автор объясняет, для чего нужен Pin и почему решения, предлагаемые на замену, не подходят и были в конечном счёте отброшены при дизайне async/await. В конце автор расписывает проблемы с Pin — включая эргономические.
В статье Pinned places лодочник рассказывает о возможном обратно совместимом расширении языка, которое интегрирует закрепление мест (places в терминологии Rust reference) в язык глубже. Как показывает автор, это позволяет значительно удобнее писать низкоуровневый (в стиле вызова poll) асинхронный код — без лишнего unsafe и с гораздо более прозрачным pin projection.
Лично я считаю предлагаемое расширение языка с моей дилетантской точки зрения довольно перспективным.
Лодочник пишет о Pin.
Именно, в первой статье — Pin — автор объясняет, для чего нужен Pin и почему решения, предлагаемые на замену, не подходят и были в конечном счёте отброшены при дизайне async/await. В конце автор расписывает проблемы с Pin — включая эргономические.
В статье Pinned places лодочник рассказывает о возможном обратно совместимом расширении языка, которое интегрирует закрепление мест (places в терминологии Rust reference) в язык глубже. Как показывает автор, это позволяет значительно удобнее писать низкоуровневый (в стиле вызова poll) асинхронный код — без лишнего unsafe и с гораздо более прозрачным pin projection.
Лично я считаю предлагаемое расширение языка с моей дилетантской точки зрения довольно перспективным.
👍9❤1
#music
Из сюрреалистичного шутера Post void.
karlflodin.bandcamp.com/track/post-void-single-feat-ycjy
Из сюрреалистичного шутера Post void.
karlflodin.bandcamp.com/track/post-void-single-feat-ycjy
Karl Flodin
POST VOID SINGLE (feat. YCJY), by Karl Flodin
track by Karl Flodin
#prog #article
A type system for RCL
Implementing a typechecker in Rust
Статья о некоторых деталях реализации тайпчекера разработанного автором языка конфигурации, который является ML-like расширением над JSON.
Это четвёртая статья в серии об этом языке, так что рекомендую также прочитать предыдущие.
В более ранней статье A reasonable configuration language автор рассказывает, что побудило его на разработку нового языка. В качестве неожиданного побочного эффекта он получил более удобную (для него) замену jq.
A type system for RCL
Implementing a typechecker in Rust
Статья о некоторых деталях реализации тайпчекера разработанного автором языка конфигурации, который является ML-like расширением над JSON.
Это четвёртая статья в серии об этом языке, так что рекомендую также прочитать предыдущие.
В более ранней статье A reasonable configuration language автор рассказывает, что побудило его на разработку нового языка. В качестве неожиданного побочного эффекта он получил более удобную (для него) замену jq.
Ruudvanasseldonk
A type system for RCL: Implementing a typechecker in Rust
I am adding a type system to RCL, my configuration language. In part 4, we look at how the typechecker is implemented in Rust, and at how it is able to generate good error messages.
👍1💩1