#prog #amazingopensource
typos — source code spell checker
Finds and corrects spelling mistakes among source code:
* Fast enough to run on monorepos
* Low false positives so you can run on PRs
github.com/crate-ci/typos
Разумеется, можно настроить исключения, на которые линтер не будет реагировать.
typos — source code spell checker
Finds and corrects spelling mistakes among source code:
* Fast enough to run on monorepos
* Low false positives so you can run on PRs
github.com/crate-ci/typos
Разумеется, можно настроить исключения, на которые линтер не будет реагировать.
🤔8👍4🔥2
Блог*
#prog #rust #article Rust threads on the GPU
#prog #rust #article
Rust SIMD on the GPU
Код на Rust, использующий
К сожалению, на текущий момент применимость этого подхода несколько ограничена, поскольку
Rust SIMD on the GPU
Код на Rust, использующий
core::simd, может быть использован на GPU без изменений на уровне исходников!К сожалению, на текущий момент применимость этого подхода несколько ограничена, поскольку
core::simd всё ещё закрыта за фичей portable_simd, и авторам пришлось внести изменения в компилятор для устранения оверхеда.Vectorware
Rust SIMD on the GPU
GPU code can now use Rust's portable SIMD. We share the implementation approach and what this unlocks for GPU programming.
🔥5👍3❤2
#prog #rust #article
Downcasting Arcs in Rust
...И о том, как можно (небезопасно) сделать это настолько дешёвым, насколько возможно
Downcasting Arcs in Rust
...И о том, как можно (небезопасно) сделать это настолько дешёвым, насколько возможно
👍1🤔1
#prog #rust #menacingopensource
nil
nil
🦀🚀🔥 A blazingly fast and memory-efficient implementation of if err != nil 🔥🚀🦀
use nil::*;
fn thing() -> (isize, error) {
(1, nil)
}
fn main() {
let (n, err) = thing();
if err != nil {
println!("Oh no!");
}
println!("Got {n}.");
}
😁27😭12
#prog #rust #article
Protecting the Rust standard library from accidental breakage
Protecting the Rust standard library from accidental breakage
Accidental breakage can happen in any codebase. The Rust standard library isn't magically exempt from this — so it too now uses cargo-semver-checks to prevent accidental breakage. Here's why this took months of work by multiple Rustaceans, dozens of pull requests, and 15,000+ lines of code across the Rust repo, cargo-semver-checks, and its component libraries.
😁5🤔2👍1
👍9🔥6
#prog #rust #rustreleasenotes
Вышел Rust 1.98.0! Как всегда, кусочки — тут, мясо — там.
▪️Обычно я пишу про новые вещи в порядке: фичи языка, добавления в std, изменения в cargo. В этот раз я напишу сначала про фичу, которая номинально является новым API в std, но которая даёт возможности, ранее невыразимые в языке (без использования интринсиков, по крайней мере).
Как известно, типы с плавающей точкой не обладают свойствами, которые имеются у действительных чисел в математике — в частности, у чисел с плавающей точкой сложение не является ассоциативной операцией. Это связывает руки оптимизатору, который обязан предохранять поведение. Например, если есть код типа
, то компилятор обязан генерировать код, который считывает и суммирует произведения чисел из слайсов по одному. Он не может, скажем, векторизовать код, поскольку подобная трансформация неизбежно меняет порядок, в котором суммируются числа, и это может заметно повлиять на результаты (это, кстати, был мотивирующий пример для предложения добавить API, описанный ниже).
Типы
, и тогда генерируемый код теперь использует SIMD и на процессорах, поддерживающих набор инструкций AVX2, код может работать до восьми раз быстрее!
Данные операции идейно схожи с ключами
▪️Компилятор теперь реагирует на
▪️Компилятор теперь предупреждает, если функция возвращает
▪️Атрибут
▪️
получают упрощённый вариант кода, а вот
— нет.
Вышел Rust 1.98.0! Как всегда, кусочки — тут, мясо — там.
▪️Обычно я пишу про новые вещи в порядке: фичи языка, добавления в std, изменения в cargo. В этот раз я напишу сначала про фичу, которая номинально является новым API в std, но которая даёт возможности, ранее невыразимые в языке (без использования интринсиков, по крайней мере).
Как известно, типы с плавающей точкой не обладают свойствами, которые имеются у действительных чисел в математике — в частности, у чисел с плавающей точкой сложение не является ассоциативной операцией. Это связывает руки оптимизатору, который обязан предохранять поведение. Например, если есть код типа
fn dot(a: &[f32], b: &[f32]) -> f32 {
let mut sum = 0.0;
for i in 0..a.len() {
sum += a[i] * b[i];
}
sum
}, то компилятор обязан генерировать код, который считывает и суммирует произведения чисел из слайсов по одному. Он не может, скажем, векторизовать код, поскольку подобная трансформация неизбежно меняет порядок, в котором суммируются числа, и это может заметно повлиять на результаты (это, кстати, был мотивирующий пример для предложения добавить API, описанный ниже).
Типы
f32 и f64 (а также f16 и f128, но их ещё не стабилизировали) обзавелись методами algebraic_{add, sub, mul, div, rem}. Они выполняют указанные арифметические операции, но, в отличие от обычных арифметических операций, оптимизатор может переупорядочивать их, используя тождества, справедливые для действительных чисел и, вообще говоря, неверные для чисел с плавающей точкой. Взамен компилятор в состоянии оптимизировать код значительно лучше — в частности, пример выше можно переписать в видеfn dot(a: &[f32], b: &[f32]) -> f32 {
let mut sum = 0.0f32;
for i in 0..a.len() {
sum = sum.algebraic_add(a[i].algebraic_mul(b[i]));
}
sum
}, и тогда генерируемый код теперь использует SIMD и на процессорах, поддерживающих набор инструкций AVX2, код может работать до восьми раз быстрее!
Данные операции идейно схожи с ключами
-ffast-math, но обладают большей гранулярностью и, в отличие от них, не страдают от драконовских ограничений в виде UB на операциях с NaN.▪️Компилятор теперь реагирует на
#[no_mangle] функции, которые некорректно переопределяют функции, ожидаемые рантаймом (ошибка компиляции) и ожидаемые std (предупреждение).▪️Компилятор теперь предупреждает, если функция возвращает
core::ffi::c_void по значению. Тип void в C и C++ отображается на () в Rust, а c_void нужно использовать, только через указатель.▪️Атрибут
#[repr(transparent)] можно применить на структуру, где одно поле "значимо", а остальные имеют "тривиальные" типы. Ранее ими считались все типы нулевого размера с единичным выравниванием, но с этой версии из этого списка исключили #[repr(C)] типы, типы с приватными полями и #[non_exhaustive] типы.▪️
#[derive(PartialOrd)] в генерируемом коды теперь просто возвращает Some(self.cmp(rhs)), если используется одновременно с #[derive(Ord)]. Из-за ограничений инфраструктуры по раскрытию макросов есть забавная особенность: комбинации#[derive(PartialOrd, Ord)]
struct A;
#[derive(Ord, PartialOrd)]
struct B;
#[derive(Ord)]
#[derive(PartialOrd)]
struct C;
получают упрощённый вариант кода, а вот
#[derive(PartialOrd)]
#[derive(Ord)]
struct D;
— нет.
❤14
Блог*
#prog #rust #rustreleasenotes Вышел Rust 1.98.0! Как всегда, кусочки — тут, мясо — там. ▪️Обычно я пишу про новые вещи в порядке: фичи языка, добавления в std, изменения в cargo. В этот раз я напишу сначала про фичу, которая номинально является новым API…
#prog #rust
Ииииии на этой версии обнаружили P-Critical баг: компилятор может генерировать vtable с null. К счастью, должны пофиксить быстро, потому что на бете уже не воспроизводится.
Ииииии на этой версии обнаружили P-Critical баг: компилятор может генерировать vtable с null. К счастью, должны пофиксить быстро, потому что на бете уже не воспроизводится.
😁12🫡5👍1
#prog #rust
В Rust стабилизировали тип never. Да, опять. Но на этот раз вроде окончательно, все крейты, сломанные из-за смены фоллбека или получили апдейты, или дико старые. Если всё пройдёт гладко, дойдёт до stable в красивой версии 1.100.
В Rust стабилизировали тип never. Да, опять. Но на этот раз вроде окончательно, все крейты, сломанные из-за смены фоллбека или получили апдейты, или дико старые. Если всё пройдёт гладко, дойдёт до stable в красивой версии 1.100.
🔥19❤2
#prog #rust #article
Replacing a Rust Enum with a 64-bit Word Made My Interpreter 17% Faster
Replacing a Rust Enum with a 64-bit Word Made My Interpreter 17% Faster
<...> That being said, sha256_unfixed is still running 12% faster with the new value representation than with the old version, even though it's allocating a total of 3,149,052 boxed integer values in a span of about 490 ms. That seemed a bit crazy to me, but having a copying GC with a bump allocator means that we can allocate objects really fast.
👍5🫡2
#prog #rust #article
How we saved 100 terabytes of memory by optimizing 1.1.1.1’s DNS cache
Большая часть изменений довольно простая.
How we saved 100 terabytes of memory by optimizing 1.1.1.1’s DNS cache
Big Pineapple, the platform behind 1.1.1.1, Gateway DNS, DNS Firewall, AS112, and several other Cloudflare DNS services, stores over 250 billion DNS cache entries at any given time. At that scale, wasting a single byte per entry costs more than 250 gigabytes of memory across our fleet.
Five successive changes to how cache entries are stored in memory cut the per-entry footprint by over 50%. Across our fleet, these changes freed up roughly 100 terabytes of memory, equivalent to the amount of RAM in 130 of our Gen 13 servers. The cache also got faster. Insert throughput rose 43% and lookup latency dropped 19%, as fewer allocations and better memory locality meant we did not trade speed for space.
Большая часть изменений довольно простая.
🎉7🔥2🤔2
#prog #rust #article
How I made Rustdoc 33% faster in one week
How I made Rustdoc 33% faster in one week
More than any technical detail, the learnings I most want you to take away are to trust your instincts and to question assumptions. Just because a piece of code (or anything, not just code!) has been a certain way for a long time doesn’t mean that it’s optimal or even correct.
👍7❤1
#prog #js #abnormalprogramming #article
The Depths of JavaScript: Minesweeper in 247 Bytes
The Depths of JavaScript: Minesweeper in 247 Bytes
b=e=>document.body.innerHTML=m(73,e||[~9,..."1172711",~9].map(j=>m[i-=j]?++e:i).map(j=>b(b[i=j]^1|e),b[i]=!m[O--,i]*~e));b(m=t=>t--?`<a onmouseup=b(b[i=${t}]^=event.which)>${t%9?"*#F"[x=b[t]??=(O-=m[t]=Math.random()<.1,1)]??~x:"<p>"}`+m(t):O,O=64)🔥12😱1
#prog #rust #article
iddqd, or the hardest kind of unsafe Rust
iddqd, or the hardest kind of unsafe Rust
I’m the main author of iddqd, a Rust library for maps (named after the Doom cheat code) where keys are borrowed from values. <...>
iddqd consists of a fair amount of unsafe code underneath. There’s been some recent concern over the amount of unsafe code in Rust rewrites, so I thought I’d write about some of the unsafe code in iddqd and how we try to tame it.
🤔3
#prog #article
Implementing FMA and finding bugs in C and Rust standard libraries
Implementing FMA and finding bugs in C and Rust standard libraries
This is a story of how I tried to compute a * b + c, and found that Rust and musl libc get it subtly wrong.🤯7👍1
Блог*
#prog #rust #article Replacing a Rust Enum with a 64-bit Word Made My Interpreter 17% Faster <...> That being said, sha256_unfixed is still running 12% faster with the new value representation than with the old version, even though it's allocating a total…
#prog #rust #article
Plush's New Register-Based Interpreter Is Insanely Fast
Plush's New Register-Based Interpreter Is Insanely Fast
I'll go into some detail on how the interpreter was rewritten to switch from a stack-based design like CPython, to a register-based design like Lua, and optimized to deliver some surprising, and I think pretty impressive results. One thing I'll say right away is that if you care about interpreter performance, you probably should not be writing stack-based bytecode interpreters in 2026.
🤔6👍1🔥1
#prog #rust #article
Could Cargo's scheduler be better?
Автор поста собрала записи того, сколько времени уходит на компиляцию каждого крейта во время сборки разных проектов, и решила проверить, можно ли было ускорить сборку за счёт использования порядка сборки, отличного от того, что используется в cargo. В качестве приоритета она использовала т. н. b-level — фактически критический путь в графе зависимостей в терминах длительности компиляции.
TL;DR: этот гипотетический вариант эффективнее cargo и переживает добавление нормально распределённого шума (с разбросом ±60%) и схлопывание информации о длительности до одного бита (долго/недолго).
Could Cargo's scheduler be better?
Автор поста собрала записи того, сколько времени уходит на компиляцию каждого крейта во время сборки разных проектов, и решила проверить, можно ли было ускорить сборку за счёт использования порядка сборки, отличного от того, что используется в cargo. В качестве приоритета она использовала т. н. b-level — фактически критический путь в графе зависимостей в терминах длительности компиляции.
TL;DR: этот гипотетический вариант эффективнее cargo и переживает добавление нормально распределённого шума (с разбросом ±60%) и схлопывание информации о длительности до одного бита (долго/недолго).
❤5👍1
#prog #rust #rustlib #article
The Design Behind wincode, a Faster Rust Serializer
TL;DR: запись в предоставленный MaybeUninit буфер, батчинг валидаций для последовательностей "простых" значений, специализация по типам, использующая сгенерированную derive-макросами метаинформацию (facet на минималках)
The Design Behind wincode, a Faster Rust Serializer
wincode is a fast, bincode-wire-compatible serializer and deserializer for Rust, built by Anza originally for the Agave validator. It is not a fork of bincode. It is a new implementation with its own traits and derive macros that produces the same bytes as bincode's default configuration
TL;DR: запись в предоставленный MaybeUninit буфер, батчинг валидаций для последовательностей "простых" значений, специализация по типам, использующая сгенерированную derive-макросами метаинформацию (facet на минималках)
🔥3🤔1
#prog #rust #article
Proving my Rust NVR doesn't leak memory (it did)
К сожалению, описанные методы диагностирования специфичны для MacOS
Proving my Rust NVR doesn't leak memory (it did)
К сожалению, описанные методы диагностирования специфичны для MacOS
🤔2