Forwarded from kosmonozhka
Совет №23.
О здоровых карьерных перспективах.
#kosmonozhka
#100_советов_художнику
(PS. Я, кстати, в своё время тоже не поступила. И ладно бы в Венскую академию, это было бы ещё не так обидно. Но нет.)
О здоровых карьерных перспективах.
#kosmonozhka
#100_советов_художнику
(PS. Я, кстати, в своё время тоже не поступила. И ладно бы в Венскую академию, это было бы ещё не так обидно. Но нет.)
🤔5🌚5❤2💩2
Forwarded from Love. Death. Transformers.
This media is not supported in your browser
VIEW IN TELEGRAM
💯20😁9❤2🖕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
Forwarded from ASCII-Nova 🇺🇦
KotlinLLM is Going Open Source - The JetBrains Blog
https://blog.jetbrains.com/research/2026/07/kotlinllm-open-source/
забавно, раньше мы шутили, что будут такие функции, но похоже дошутились :)
💩21😁6😱2
#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
👍8🔥6
#gamedev
Разработчики #game Artisan of Glimmith (советую btw) недавно опубликовали пост про апдейт, главной темой которого была в основном оптимизация. Пост советую к прочтению целиком, отчасти из-за того, что для, в общем-то, относительно казуальной игры подобные технические моменты разработчики обычно освещают редко.
Из занятных моментов могу отметить, что разработчики перенесли обработку частиц с GPU на CPU. Как оказалось, в игре они используются с достаточно небольшом количестве, чтобы оверхед на вызовы графического API каждый кадр и перенос данных на GPU перекрывал выгоды от параллелизации. Более того, после удаления этих вызовов суммарная нагрузка на CPU в итоге снизилась — даже на CPU эти расчёты занимают меньше времени, чем общение с видеокартой.
Разработчики #game Artisan of Glimmith (советую btw) недавно опубликовали пост про апдейт, главной темой которого была в основном оптимизация. Пост советую к прочтению целиком, отчасти из-за того, что для, в общем-то, относительно казуальной игры подобные технические моменты разработчики обычно освещают редко.
Из занятных моментов могу отметить, что разработчики перенесли обработку частиц с GPU на CPU. Как оказалось, в игре они используются с достаточно небольшом количестве, чтобы оверхед на вызовы графического API каждый кадр и перенос данных на GPU перекрывал выгоды от параллелизации. Более того, после удаления этих вызовов суммарная нагрузка на CPU в итоге снизилась — даже на CPU эти расчёты занимают меньше времени, чем общение с видеокартой.
🤔10👍4🌚1
#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;
— нет.
❤10
▪️Стабилизировали API:
🔸format_into на примитивных числовых типах (и используемый аргументом fmt::NumBuffer) для форматирования числа в переданный по ссылке буфер. Это избегает использования оверхеда от
🔸str::substr_range и <[T]>::subslice_range, которые возвращают диапазон, в котором располагается переданная подстрока/подслайс. Эти методы не смотрят на содержимое самой строки, а вычисляют позицию, используя сравнения указателей, поэтому на посторонних аргументах (не лежащих внутри
🔸NonZero::from_str_radix. Ошибка от этого метода может возвращать из метода kind значение IntErrorKind::Zero.
🔸
🔸str::strip_circumfix и <[T]>::strip_circumfix, которые возвращают строку/слайс без указанных префикса и суффикса. Возвращает
🔸
🔸format_into на примитивных числовых типах (и используемый аргументом fmt::NumBuffer) для форматирования числа в переданный по ссылке буфер. Это избегает использования оверхеда от
write! и может сильно повысить производительность — бенчи показывают, что новый метод по производительности сопоставим с itoa (крейт, не функция из C).🔸str::substr_range и <[T]>::subslice_range, которые возвращают диапазон, в котором располагается переданная подстрока/подслайс. Эти методы не смотрят на содержимое самой строки, а вычисляют позицию, используя сравнения указателей, поэтому на посторонних аргументах (не лежащих внутри
self) этот метод возвращает None. Документация, правда, предупреждает, что методы могут возвращать Some(0..0) или Some(self.len()..self.len()), если переданная строка/слайс пустая и лежит в памяти непосредственно до или после self.🔸NonZero::from_str_radix. Ошибка от этого метода может возвращать из метода kind значение IntErrorKind::Zero.
🔸
String::from_utf16{be, le}_{, lossy} для получения строки из UTF-16 с порядком байт, отличных от нативного.🔸str::strip_circumfix и <[T]>::strip_circumfix, которые возвращают строку/слайс без указанных префикса и суффикса. Возвращает
None, если префикс и/или суффикс не содержатся в self или если они перекрываются.🔸
Atomic<T>::{from_mut, from_mut_slice} для получения атомиков из уникальных ссылок. Уникальность ссылок гарантирует корректность этого преобразования. Также стабилизировали Atomic<T>::get_mut_slice, который является логичным продолжением уже стабильного Atomic<T>::get_mut.❤2
Блог*
#prog #rust #rustreleasenotes Вышел Rust 1.98.0! Как всегда, кусочки — тут, мясо — там. ▪️Обычно я пишу про новые вещи в порядке: фичи языка, добавления в std, изменения в cargo. В этот раз я напишу сначала про фичу, которая номинально является новым API…
#prog #rust
Ииииии на этой версии обнаружили P-Critical баг: компилятор может генерировать vtable с null. К счастью, должны пофиксить быстро, потому что на бете уже не воспроизводится.
Ииииии на этой версии обнаружили P-Critical баг: компилятор может генерировать vtable с null. К счастью, должны пофиксить быстро, потому что на бете уже не воспроизводится.
😁6🫡4