Pull to refresh
16K+
48
Morettom@morett1m

Пишу про Rust, Golang и внезапно — про мозг

110
Rating
40
Subscribers
Send message

Как Rust реализует трейт-объекты и почему dyn Trait медленнее дженериков

Reading time11 min
Reach and readers9.4K

Спросите разработчика: «Почему dyn Trait медленнее дженериков?», в 9 из 10 случаях услышите: «Потому что косвенный вызов через vtable». Один дополнительный переход по указателю, промах по кешу, вот и вся разница. Звучит убедительно, и кстати процентов на десять правда.

Настоящая цена динамической диспетчеризации не в самом прыжке через vtable, а в том, что этот прыжок прячет от оптимизатора. LLVM видит непрозрачный call по указателю и пасует. Не может встроить тело, не может раскрутить цикл, не может протащить константу через границу вызова. Один косвенный вызов и целый каскад оптимизаций становится невозможным.

Но чтобы понять, почему так происходит, нужно сначала разобраться, как dyn Trait устроен внутри. Что лежит в этом толстяке, как выглядит vtable в памяти, и чем всё это отличается от того, что делает компилятор с дженериками.

Читать далее

Subtyping и variance в Rust: о чём обычно молчат

Level of difficultyMedium
Reading time12 min
Reach and readers6.8K

Привет, Хабр!

Есть вещи в Rust, которые работают незаметно, пока не ломаются, да ломаются они странно... Компилятор указывает на место, где вы ничего плохого не делали, и говорит про «lifetime mismatch» или «mismatched types» без внятного объяснения почему. Или наоборот: вы ожидаете ошибку, потому что передаёте ссылку с явно другим временем жизни, а компилятор молчит и пропускает.

Оба случая объясняются одним механизмом: variance.

Большинство останавливаются на трёх определениях и паре примеров. Пойдём глубже — до алгебры композиции, до того, как компилятор выводит variance через итерацию фиксированной точки, до #[may_dangle] и до того, почему NonNull<T> ковариантен, а *mut T нет.

Читать далее

Rust прячет инструменты там, где вы их не ищете

Level of difficultyEasy
Reading time10 min
Reach and readers10K

Привет, Хабр!

В первой части мы разобрали never-тип !, макрос matches!, std::hint::black_box, прозрачные обёртки с repr(transparent) и transmute_copy. Если не читали — загляните, там фундаментальные штуки. Сегодня продолжаем: ещё шесть возможностей.

Читать далее

Send и Sync в Rust: что решает компилятор за вашей спиной

Level of difficultyMedium
Reading time10 min
Reach and readers9.6K

Привет, Хабр!

Сегодня рассмотрим Send и Sync. Не «что это такое» (это вы в book прочитаете за пять минут), а как именно компилятор принимает решения, почему &mut T внезапно Sync, и что происходит, когда вы пишете unsafe impl Send.

Читать далее

#[inline] в Rust — это не про инлайнинг. И вот почему вы расставляете его не там

Level of difficultyEasy
Reading time8 min
Reach and readers12K

Вы открываете горячую функцию в профилировщике, видите миллионы вызовов, добавляете #[inline(always)]. Бинарник распухает, время сборки подскакивает, а производительность не меняется. Или ваще падает. Проблема не в атрибуте. Проблема в том, что #[inline] делает совсем не то, что подсказывает интуиция.

Читать далее

Почему macro_rules! может не остановиться и что с этим делает Rust

Level of difficultyMedium
Reading time12 min
Reach and readers8.4K

Приветствую.

В 1936 году Алан Тьюринг опубликовал статью, которая среди прочего доказала одну неприятную вещь: невозможно написать алгоритм, который для любой программы и любого входа определит, остановится программа или нет. Проблема остановки. Мы натыкаемся на неё гораздо чаще, чем кажется. Иногда прямо в Cargo.toml.

Читать далее

Нестандартные фичи Rust, которые вы полюбите

Level of difficultyEasy
Reading time9 min
Reach and readers13K

Привет, Хабр! В Rust есть тип, у которого нет ни одного возможного значения. Звучит необычно. Но я однажды столкнулся с этим самым никогда‑типом и понял — без него жить в Rust уже не хочется! Что это такое и зачем нужно — разберём подробно. По ходу дела упомянем и связанные фичи: Infallible, новоявленные макросы вроде matches!, разные фишки для оптимизации кода и FFI, про которые часто не догадываешься.

Читать далее

Miri ловит то, что пропускает компилятор

Level of difficultyMedium
Reading time13 min
Reach and readers6.6K

Привет! Сегодня рассмотрим инструмент, который поможет вам с низкоуровневым кодом на Rust. Если вы пишете на Rust только безопасный код, возможно, никогда о нём не слышали.

А вот тем, кто периодически заглядывает в тёмные уголки unsafe, этот инструмент сэкономит нервишки.

Читать далее

Чатик в лесу: как шимпанзе комбинируют звуки в сложные сообщения

Level of difficultyEasy
Reading time11 min
Reach and readers9.3K

Принято думать, что у людей — сложный язык со словами и правилами, а у животных все примитивно: один крик — одно сообщение («нашёл банан», «вижу хищника» и так далее).

Шимпанзе кричат, фыркают, ухают — но это же просто шум, правда..? Ан нет! Исследование показывает, что наши волосатые родственники комбинируют свои возгласы так, что получаются как бы сложные «слова» и фразы. Причем делают они это разнообразнее, чем считалось раньше.

Читать далее

«Лучшие» практики Rust, которые вас подведут

Level of difficultyEasy
Reading time13 min
Reach and readers15K

Привет, Хабр!

Знаете, что общего между документацией Rust и советами бабушки? И то, и другое звучит разумно, пока не начнёшь применять буквально ко всему. «Используй дженерики для переиспользования кода», «оборачивай общие данные в Arc<Mutex>», «создавай типизированные ошибки» — всё это написано в книгах, статьях и туториалах. И всё это может превратить ваш проект в нечто, от чего хочется плакать.

Читать далее

Осторожно, Drop: как невинный деструктор рушит код

Level of difficultyEasy
Reading time13 min
Reach and readers9K

Сегодня мы поговорим про такую, казалось бы, простую и привычную штуку, как функция drop в языке Rust. Что может быть банальнее?

Создали переменную, и в конце области видимости она сама очистится. RAII за нас делает всю работу, а мы просто выдыхаем и не боимся утечек памяти. Но не все так радужно!

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

Читать далее

Почему мандаринка в июле телепортирует тебя в детство

Level of difficultyEasy
Reading time10 min
Reach and readers8.6K

Декабрь. За окном то ли снег, то ли дождь, в магазинах уже вовсю продают елки, а в воздухе витает этот неуловимый коктейль из хвои, мандаринов и чего-то еще, что безошибочно сигнализирует: скоро Новый год.

И вот ты стоишь где-нибудь в очереди, вдыхаешь случайно долетевший аромат цитрусовых, и тебя накрывает. Вот ты маленький, вот бабушкина квартира, вот тот самый телевизор с «Иронией судьбы», вот миска с оливье, к которой тебе еще не разрешают подходить до боя курантов.

Читать далее

Всё, что нужно знать про аллокаторы в Rust (и как написать свой)

Level of difficultyEasy
Reading time13 min
Reach and readers11K

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

Но. Как только начинаешь копать чуть глубже, выясняется, что у Rust есть вполне конкретная рука, которая раздаёт память под все эти Box::new(42), Vec::push и растущие String. Имя этой руке простое: аллокатор. Он отвечает за то, что происходит в куче, и именно через него проходят почти все интересные истории про производительность и поведение памяти.

Читать далее

Как Rust думает о памяти: &mut, provenance и noalias

Level of difficultyMedium
Reading time12 min
Reach and readers8.9K

Мы знаем, что Rust славится безопасностью и строгим контролем за доступом к данным, но за этими правилами стоит целая философия и формальная модель.

Сегодня с вами посмотрим изнанки модели памяти Rust. Поговорим о том, кто имеет право на доступ к памяти, что такое provenance указателей, почему &mut T считается эксклюзивным и как все это добралось до уровня оптимизатора LLVM через атрибут noalias.

Читать далее

Что происходит после fn main() в Rust?

Level of difficultyEasy
Reading time12 min
Reach and readers12K

Привет!

Хочу вместе с вами разобрать, как же код на Rust превращается в готовый исполняемый файл. Мы пишем программу, например, fn main() { println!("Hello, Habr!"); }, компилируем, и на выходе получаем бинарник. Что происходит под капотом компилятора Rust в этот момент? Давайте аккуратненько заглянем внутрь этого таинственного процесса.

Читать далее

Нейроны, перестановки и степень двойки — что у них общего?

Level of difficultyEasy
Reading time10 min
Reach and readers12K

Мы часто оперируем степенями двойки, будь то размеры массивов, адресация памяти или флаги настроек в битовой маске.

Казалось бы, при чём здесь мозг?

В нейробиологии давно витает идея, что нейронные сети организованы не случайно, а по неким правилам. Еще канадский психолог Дональд Хебб в 1949 году предположил, что нейронные ансамбли. Грубо говоря, если группа клеток вместе активируется при каком-то событии, она образует узнаваемый шаблон, память или образ. Но вот как именно мозг организует такие группы, оставалось загадкой.

Однако еще 10 лет назад появилась теория о том, что интеллект возникает благодаря удивительно простой математической логике связей между нейронами.

Читать далее

Закрепи меня покрепче: Pin, самоссылки и почему всё падает

Level of difficultyMedium
Reading time16 min
Reach and readers7.7K

Привет, Хабр!

Сегодня я хочу поделиться своим опытом и знаниями о pinning в Rust, замечательной конструкции Pin, которая поначалу вызывает вопросы, зачем нужен какой-то пин, если и без него всё работало?

Но вот незадача, без Pin не реализовать безопасно ни одну хитрую программку, самоссылающиеся структуры и связанные с ними асинхронные генераторы. В этой статье я расскажу, почему вообще появился Pin/Unpin, как он спасает от падений программы, и как правильно его применять на практике.

Закрепиться

5 способов убить производительность в асинхронном Rust

Level of difficultyMedium
Reading time11 min
Reach and readers10K

Привет, Хабр! В предыдущих статьях — «Rust без прикрас: где мы ошибаемся» и «Rust без прикрас: где мы продолжаем ошибаться» мы обсудили всякие неприятные грабли: бездумное использование unwrap(), игнорирование ошибок через let _ =, чрезмерное клонирование, проблемы с хвостовой рекурсией и прочие оплошности. Теперь пришло время взглянуть на другой пласт проблем.

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

Читать далее

Спермоботы атакуют

Level of difficultyEasy
Reading time16 min
Reach and readers12K

Представьте, что курьерские доставки добрались до клеточного уровня.

Мы живём в мире, где еду привозят за полчаса, а покупки на следующий день. А что если доставлять лекарства прямо внутри организма, отправляя их точно по адресу, скажем, в труднодоступный уголок человеческого тела? Звучит необычно и на первый взгляд кажется нереальным. Но недавнее научное исследование показывает, что это не такая уж и фантастика. Учёные научились превращать обычные сперматозоиды в миниатюрных биороботов, которыми можно управлять снаружи с помощью магнитного поля и даже видеть их на рентгене. Такой вот управляемый биоробот.

Статья подготовлена на основе научной публикации.

Читать далее

Всё что нужно и не нужно знать про заимствование в Rust

Level of difficultyMedium
Reading time16 min
Reach and readers11K

Привет, Хабр!

Сегодня я хочу поговорить о заимствованиях в Rust – теме, которая очевидно вводит многих в заблуждения но первых порах, но жизненно необходима для каждого, кто хочет писать на Rust. Мы с вами разберём, зачем Rust ввёл эту концепцию, как она работает под капотом, и какие нюансы следует знать, чтобы подружиться с borrow checker’ом, а не воевать с ним каждый раз при компиляции кода.

Читать далее
1

Information

Rating
79-th
Location
Aisaroaivve, None, Норвегия
Date of birth
Registered
Activity

Specialization

Бэкенд разработчик
Средний
Rust
Высоконагруженные системы
SQL
Английский язык
PostgreSQL