Rust. The Computer Language Benchmarks Game
Что-то где-то обновилось, пересчиталось, и я, неожиданно для себя, вылез на первое место по Rust в k-nucleotide benchmark, причём даже с небольшим заделом:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/knucleotide.html
C++ по-прежнему кажется недостижимым - чтобы посоревноваться за первое - нужен быстрый hashmap со специализацией по типам.
#rust #bench #old
Что-то где-то обновилось, пересчиталось, и я, неожиданно для себя, вылез на первое место по Rust в k-nucleotide benchmark, причём даже с небольшим заделом:
https://benchmarksgame-team.pages.debian.net/benchmarksgame/performance/knucleotide.html
1. C++ g++ #2
3.66 155,956 1624 11.16 70% 98% 70% 68%
2. C gcc
5.07 130,008 1506 15.25 88% 84% 58% 73%
3. C# .NET Core #9
5.29 186,892 2574 17.90 96% 67% 93% 84%
4. Rust #8
5.76 135,728 1900 16.77 84% 94% 49% 65%
5. Rust #4
6.07 137,948 1749 18.11 51% 81% 78% 90%
C++ по-прежнему кажется недостижимым - чтобы посоревноваться за первое - нужен быстрый hashmap со специализацией по типам.
#rust #bench #old
❤1
coinbase-pro-rs
Запилил API на расте для работы с coinbase-pro: https://crates.io/crates/coinbase-pro-rs
поддерживает в том числе futures и websocket.
Ордербук пока положил отдельно - в связке он мне пока не нужен - но как только, так сразу его затащу внутрь.
#rust #old
Запилил API на расте для работы с coinbase-pro: https://crates.io/crates/coinbase-pro-rs
поддерживает в том числе futures и websocket.
Ордербук пока положил отдельно - в связке он мне пока не нужен - но как только, так сразу его затащу внутрь.
#rust #old
Rust, рефакторинг
Всё работало, вроде неплохо, пока не подключил extern crate pyo3. Естественно всё просто в Rust быть не может - не могу обернуть структуру с лайфтаймами макросами pyo3 => начался глобальный рефакториг по вычищению от лайфтаймов довольно центральной структуры => всё замазывается толстым слоем Rc/Arc/RefCell, настолько толстым, что хотется начать писать на Swift.
что-то типа такого:
self.borrow().control.borrow().stats.borrow_mut().counter += 1;
какой приятный код :(
При этом это по сути убивает всю lifetime концепцию - так как каждый borrow - это твой личный и ручной контроль поверх раста.
#rust #old
Всё работало, вроде неплохо, пока не подключил extern crate pyo3. Естественно всё просто в Rust быть не может - не могу обернуть структуру с лайфтаймами макросами pyo3 => начался глобальный рефакториг по вычищению от лайфтаймов довольно центральной структуры => всё замазывается толстым слоем Rc/Arc/RefCell, настолько толстым, что хотется начать писать на Swift.
что-то типа такого:
self.borrow().control.borrow().stats.borrow_mut().counter += 1;
какой приятный код :(
При этом это по сути убивает всю lifetime концепцию - так как каждый borrow - это твой личный и ручной контроль поверх раста.
#rust #old
Rust - опять
Есть у меня pet-проект, который тянется уже больше года и, постепенно, подходит к финальному аккорду.
В какой-то момент было решено изменить способ хранения данных у клиента на простые файлы => понадобилась некая скачивался данных из базы для этого, всё работало почти отлично - данные качались чанк за чанком, прогрес-бар показывал сколько осталось. Кроме одного - данные не сжаты и их много - отдавать потоком - остаться без Content-Length - пользователь будет в неведении сколько осталось. Сжимать сразу много - пользователю очень долго ждать этого Content-Length.
Было решено просто - собирать по 1000, сжимать и отдавать - всё опять же работало, но что-то было странно - иногда некоторые чанки приходили битыми. Посмотрев на пакеты стало понятно - что пакеты нормальные, а вот способ их обработки у hyper такой - если chunk не влезает в буффер (8kb) - то выдавать chunk с тем что есть, а остальное - как будто это другой чанк. Насколько это корректное поведение не берусь судить, возможно и верное. Хотел было переехать на web-sockets, и тут, actix-web, казавшийся нормальным в качестве http показал, что структура для ws должна делаться так:
Дальше надо описать актор, потом Handler, потом ещё StreamHandler, в который надо передать mut-контекст этого клиента, после чего из него дёргать руками методы типа ctx.0.write или обёртки. Но это не заработает со фьючовыми стримами, потому как при создании этого клиента - надо вызвать мутабельный add_stream на нём, в котором связать Stream и контекст - видимо иначе он не будет знать что надо дёргать этот handler, при этом, даже если совершить все эти действия - это только для обработки выходного потока из stream - как писать в него из другого стрима без своего impl Stream поверх - останется загадкой.
В общем, от такого юзать ws как-то расхотелось. Знающие люди говорили, что надо просто накрутить length_delimited кодек на чанки http и у меня будут нормальные фреймы данных - попробую в эту сторону. Кодеки работают через ASyncRead, а hyper/actix выдают Stream<Item=Vec<u8>> - хотя в общем-то понятно, что результат их работы в этом случае одинаков, и только в futures 0.3 сделали метод into_async_read() который позволяет одну абстракцию преобразовывать в другую => можно просто писать в codec - ура!, но нет, не ура, tokio 0.2 почему-то имеет свои ASyncRead, которые почему-то не совместимы с futures 0.3, а другие мне не подойдут. Есть некий клей - compat, но, бывалые люди, сказали что всё же _надёжнее разобрать байты руками_, чем пробраться через страницу какой-нибудь ошибки, которую покажет compat(). Без compat() ошибки и так по пол-страницы и не сильно проще читать.
Вернёмся к тому, что я никак не ожидал - что я могу застрять на несколько недель на простой скачивалке файла чанками, a раст, в очередной раз, как говорится, пробивает дно в производительности сроков написания чего-то отличного от примеров из папки examples (кстати и это часто не собирается). И у меня много таких случаев о которых можно было бы рассказать не меньше - но первый раз, когда решил написать.
#rust #old
Есть у меня pet-проект, который тянется уже больше года и, постепенно, подходит к финальному аккорду.
В какой-то момент было решено изменить способ хранения данных у клиента на простые файлы => понадобилась некая скачивался данных из базы для этого, всё работало почти отлично - данные качались чанк за чанком, прогрес-бар показывал сколько осталось. Кроме одного - данные не сжаты и их много - отдавать потоком - остаться без Content-Length - пользователь будет в неведении сколько осталось. Сжимать сразу много - пользователю очень долго ждать этого Content-Length.
Было решено просто - собирать по 1000, сжимать и отдавать - всё опять же работало, но что-то было странно - иногда некоторые чанки приходили битыми. Посмотрев на пакеты стало понятно - что пакеты нормальные, а вот способ их обработки у hyper такой - если chunk не влезает в буффер (8kb) - то выдавать chunk с тем что есть, а остальное - как будто это другой чанк. Насколько это корректное поведение не берусь судить, возможно и верное. Хотел было переехать на web-sockets, и тут, actix-web, казавшийся нормальным в качестве http показал, что структура для ws должна делаться так:
Client<SinkWrite<Message, SplitSink<Framed<T, Codec>, Message>>>
- просто же, и удобно - все кишки видны, а то мало ли нужно будет из client.0.0.0 извлечь codec.Дальше надо описать актор, потом Handler, потом ещё StreamHandler, в который надо передать mut-контекст этого клиента, после чего из него дёргать руками методы типа ctx.0.write или обёртки. Но это не заработает со фьючовыми стримами, потому как при создании этого клиента - надо вызвать мутабельный add_stream на нём, в котором связать Stream и контекст - видимо иначе он не будет знать что надо дёргать этот handler, при этом, даже если совершить все эти действия - это только для обработки выходного потока из stream - как писать в него из другого стрима без своего impl Stream поверх - останется загадкой.
В общем, от такого юзать ws как-то расхотелось. Знающие люди говорили, что надо просто накрутить length_delimited кодек на чанки http и у меня будут нормальные фреймы данных - попробую в эту сторону. Кодеки работают через ASyncRead, а hyper/actix выдают Stream<Item=Vec<u8>> - хотя в общем-то понятно, что результат их работы в этом случае одинаков, и только в futures 0.3 сделали метод into_async_read() который позволяет одну абстракцию преобразовывать в другую => можно просто писать в codec - ура!, но нет, не ура, tokio 0.2 почему-то имеет свои ASyncRead, которые почему-то не совместимы с futures 0.3, а другие мне не подойдут. Есть некий клей - compat, но, бывалые люди, сказали что всё же _надёжнее разобрать байты руками_, чем пробраться через страницу какой-нибудь ошибки, которую покажет compat(). Без compat() ошибки и так по пол-страницы и не сильно проще читать.
Вернёмся к тому, что я никак не ожидал - что я могу застрять на несколько недель на простой скачивалке файла чанками, a раст, в очередной раз, как говорится, пробивает дно в производительности сроков написания чего-то отличного от примеров из папки examples (кстати и это часто не собирается). И у меня много таких случаев о которых можно было бы рассказать не меньше - но первый раз, когда решил написать.
#rust #old
Rust - достаточно
Rust практически вылетел из зоны моих интересов, жаль что довольно большой проект на нём застрял.
Ситуация такая: я уже почти увидел свет в конце тоннеля по проекту, но, на клиентской стороне использовать монгу не решился => нужно уметь читать данные как из монги так и из локальных файлов. В качестве такого решения напрашивается некий trait Storage, который реализует функцию создания итератора для структур Mongo и Local (из файла). Итераторы соответственно MongoIterator и LocalIterator которые реализуют просто Iterator. Проще, вроде как, и придумать трудно.
Собственно всё, что Local можно отбросить, чтобы просто сделать MongoIterator - надо в ней хранить и коллекцию и курсор, а это уже получается self-referential структура, после двух недель борьбы с Pin и unsafe (не смотря на то что пример вроде как есть тут: https://doc.rust-lang.org/std/pin/#example-self-referential-struct , но это не очень помогло), знающие люди подсказали поискать в крейтах, и действительно, нашёлся некий https://crates.io/crates/rental , который естественно полон макросов, а куда в расте без них, которые генерят это self-ref с лайфтаймами друг на друге и функции для их извлечения.
Кое-как всё пройдено, сам крейт проекта нормально собирается, теперь надо просто использовать это в бинарнике - и тут хоп - эта вот штука ещё используется, хотя вот тут уже конец блока, чуть ли не в main, с какой такой стати, почему - не ясно вообще, у меня уже начали опускаться руки, попытки понять лайфтаймов макросов, генерящих Pin, не сильно обрадовали и я пошёл искать тех самых знающих людей, которых мне помогут. Люди, как мне кажется, действительно знающие, нашлись и даже принялись за проблему, починили за час ... но нет, я просто случайно закомментил весь значимый код, раскомментил, и люди пришли к выводу, что разобраться в чём дело не удаётся. А это по сути просто интерфейс Storage - проще, мне кажется, и придумать нельзя.
На этом я решил, что больше свои руки, без необходимости, в это опускать не буду. Я благодарен расту за эксперимент-попытку поставить как основу всей системы move-семантику из плюсов, но это так просто не работает - ты бродишь по лабиринту, пытаясь удовлетворить borrow-чекер больше чем пишешь программу, повезло - вышел из лабиринта, не повезло - ты возвращаешься на много шагов назад и не факт, что выход в итоге есть. Иногда это интересная головоломка, но иногда, потратив на неё месяцы и опять оказавшись в тупике, ты понимаешь что это уже не смешно, работающего кода это не прибавило, а время потрачено без какой-то, ощутимой для проекта, пользы.
--- update ---
через три дня, мне постучались в телегу, и сказали, что не спали три ночи, но проблему исправили - ура.
#rust #old
Rust практически вылетел из зоны моих интересов, жаль что довольно большой проект на нём застрял.
Ситуация такая: я уже почти увидел свет в конце тоннеля по проекту, но, на клиентской стороне использовать монгу не решился => нужно уметь читать данные как из монги так и из локальных файлов. В качестве такого решения напрашивается некий trait Storage, который реализует функцию создания итератора для структур Mongo и Local (из файла). Итераторы соответственно MongoIterator и LocalIterator которые реализуют просто Iterator. Проще, вроде как, и придумать трудно.
Собственно всё, что Local можно отбросить, чтобы просто сделать MongoIterator - надо в ней хранить и коллекцию и курсор, а это уже получается self-referential структура, после двух недель борьбы с Pin и unsafe (не смотря на то что пример вроде как есть тут: https://doc.rust-lang.org/std/pin/#example-self-referential-struct , но это не очень помогло), знающие люди подсказали поискать в крейтах, и действительно, нашёлся некий https://crates.io/crates/rental , который естественно полон макросов, а куда в расте без них, которые генерят это self-ref с лайфтаймами друг на друге и функции для их извлечения.
Кое-как всё пройдено, сам крейт проекта нормально собирается, теперь надо просто использовать это в бинарнике - и тут хоп - эта вот штука ещё используется, хотя вот тут уже конец блока, чуть ли не в main, с какой такой стати, почему - не ясно вообще, у меня уже начали опускаться руки, попытки понять лайфтаймов макросов, генерящих Pin, не сильно обрадовали и я пошёл искать тех самых знающих людей, которых мне помогут. Люди, как мне кажется, действительно знающие, нашлись и даже принялись за проблему, починили за час ... но нет, я просто случайно закомментил весь значимый код, раскомментил, и люди пришли к выводу, что разобраться в чём дело не удаётся. А это по сути просто интерфейс Storage - проще, мне кажется, и придумать нельзя.
На этом я решил, что больше свои руки, без необходимости, в это опускать не буду. Я благодарен расту за эксперимент-попытку поставить как основу всей системы move-семантику из плюсов, но это так просто не работает - ты бродишь по лабиринту, пытаясь удовлетворить borrow-чекер больше чем пишешь программу, повезло - вышел из лабиринта, не повезло - ты возвращаешься на много шагов назад и не факт, что выход в итоге есть. Иногда это интересная головоломка, но иногда, потратив на неё месяцы и опять оказавшись в тупике, ты понимаешь что это уже не смешно, работающего кода это не прибавило, а время потрачено без какой-то, ощутимой для проекта, пользы.
--- update ---
через три дня, мне постучались в телегу, и сказали, что не спали три ночи, но проблему исправили - ура.
#rust #old
👍1
100M Taxi Rides benchmark. 3/3 - не туда свернул
Пройду по в-каждой-бочке-затычка-Rust, так как на него ушло больше всего времени:
Итого, На C или Nim решение в лоб пишется за 10-15минут. Лучшее время
- Выяснилось, что за два года встроенные бенчмарки как были в nightly так там и остались, criterion заработал.
- Нужные интрисики нашлись в
- Макросы везде - уже начав профилировать ещё раз переспросил в чате что не уверен про
- Показательный пример, это ручное разворачивание цикла - понадеявшись это сделать просто - одной-двумя строками шаблона, но не вышло и я обратился к старожилам. Замечу, что и для них эта задача оказалась не очень простой по причине специфики макросов раста и пришлось применить чужой крейт, но и тут не так всё просто - крейт собирался под nightly-только, хотя починить легко. Казалось бы, всё просто, но дежавю - раст это всегда тяжело: https://t.me/inv2004_dev_blog/29
- В итоге Rust выдал вполне хороший результат с временем 13.11ms
- Это всё про unsafe, пошёл разговор, что safe в nightly лучше чем unsafe в stable - мне пришлось закатать рукава и посмотреть на
- Ну, и не стоить забывать, что этот крейт уже забросили - классика раста. Так что ориентир на производительность при таком SIMD под вопросом.
- Сам бенч тут: https://github.com/inv2004/100m_taxi_bench/
Так что, окунувшись в раст на несколько вечеров я немного огорчён тем что, казалось популярность растёт, но каких-то знаковых отличий от того что было два года назад я не заметил. Всё так же stable не слишком популярен. Issue, про генераторы висит открытым два года - всё ещё оптимизируют минимальный пример. И, самое главное, - макросы наступают, кажется что большинство проблем раста обходят именно макросами, которых, кажется, уже перебор. Не уверен что вообще остались крейты где не пришлось бы изучать новые макросы, а при отладке и того хуже. Брр, изначально тема была не про раст, но я скатился.
#bench #rust
Пройду по в-каждой-бочке-затычка-Rust, так как на него ушло больше всего времени:
Итого, На C или Nim решение в лоб пишется за 10-15минут. Лучшее время
11.89ms
в режиме -d:danger
, в немного более безопасном -d:release
13.79ms
. А вот с Rust всё было интереснее и даже немного ностальгически, и тут я подробнее:- Выяснилось, что за два года встроенные бенчмарки как были в nightly так там и остались, criterion заработал.
- Нужные интрисики нашлись в
core::arch
, но первая реализация показала какое-то жуткое время 300ms, пришлось идти на godbolt https://rust.godbolt.org/z/bW6EaK7f1 . Оказалось, что надо руками указать target-feature=+avx2
и непонятный +popcnt
и только тогда они станут нормально инлайниться. С этим разобрались - инлайнится, но не сильно помогло ...- Макросы везде - уже начав профилировать ещё раз переспросил в чате что не уверен про
addr_of!
, и, действительно, кто-то, раскрыв макрос, указал на ошибку где я дважды делал deref - большое спасибо ему. С одной стороны я сам виноват - не очень внимательно разглядел что макрос сам делает &
, с другой, если в языке даже для взятия указателя нужен макрос. Какие-то гарантии на макросах предоставить сложно - надо или очень внимательно читать описание или, ещё надёжнее, читать во что он раскроется. Макрос пришлось применить, потому как иначе нужно делать двойной каст, хотя зачем это так - я с ходу не понял.- Показательный пример, это ручное разворачивание цикла - понадеявшись это сделать просто - одной-двумя строками шаблона, но не вышло и я обратился к старожилам. Замечу, что и для них эта задача оказалась не очень простой по причине специфики макросов раста и пришлось применить чужой крейт, но и тут не так всё просто - крейт собирался под nightly-только, хотя починить легко. Казалось бы, всё просто, но дежавю - раст это всегда тяжело: https://t.me/inv2004_dev_blog/29
- В итоге Rust выдал вполне хороший результат с временем 13.11ms
- Это всё про unsafe, пошёл разговор, что safe в nightly лучше чем unsafe в stable - мне пришлось закатать рукава и посмотреть на
packed_simd
- вроде то что надо, но не удавалось найти movemask
, хотя, видно, что они сами его используют. Начал искать, и опять наткнулся на гору макросов. Далеко не самые страшные из тех что я видел, но разбирать их не нашлось желания. Так что, я просто заменил на что-то аналогичное, но считающее не совсем верно, Не уверен, что тут вообще можно замерять при разном результате, но, как бы то ни было, в этом варианте safe выдал неплохой результат 15.36ms. Так что safe это не совсем zero-cost, а, с другой стороны, если посмотреть на issues этой обвязки - то тяжело понять много ли безопасности она добавила.- Ну, и не стоить забывать, что этот крейт уже забросили - классика раста. Так что ориентир на производительность при таком SIMD под вопросом.
- Сам бенч тут: https://github.com/inv2004/100m_taxi_bench/
Так что, окунувшись в раст на несколько вечеров я немного огорчён тем что, казалось популярность растёт, но каких-то знаковых отличий от того что было два года назад я не заметил. Всё так же stable не слишком популярен. Issue, про генераторы висит открытым два года - всё ещё оптимизируют минимальный пример. И, самое главное, - макросы наступают, кажется что большинство проблем раста обходят именно макросами, которых, кажется, уже перебор. Не уверен что вообще остались крейты где не пришлось бы изучать новые макросы, а при отладке и того хуже. Брр, изначально тема была не про раст, но я скатился.
#bench #rust
rust.godbolt.org
Compiler Explorer
Compiler Explorer is an interactive online compiler which shows the assembly output of compiled C++, Rust, Go (and many more) code.
🔥5😱4👍1
RefCell - трусы надень или крестик сними
Когда-то давно написал статью https://habr.com/ru/post/442962/, но, и до этого, и во время написания статьи меня не покидало ощущение, что костыль
С
#rust
Когда-то давно написал статью https://habr.com/ru/post/442962/, но, и до этого, и во время написания статьи меня не покидало ощущение, что костыль
RefCell<>
ломает всю концепцию borrow-checker'а, хотя это и является одной из базовых вещей в Расте. Использовать её, всё равно что использовать unsafe, но чуть с менее печальными последствиями. Программа в определённый момент может тебе сказать, причём уже только в runtime: "тут мои полномочия всё, ты как-нибудь сам", и, скорее всего, это будет значить что что-то в приложении заархитектурено не так и надо начинать сначала.С
Rc<>
проще, но к нему тоже претензии - в каком-нибудь single-threaded-async он не нужен, но в расте он будет нужен только для удовлетворения borrow-checker.#rust
Хабр
Ещё одна статья о временах жизни (lifetimes) в Rust
Первые месяцы начинающего растомана как правило сводятся к ударам головой о концепцию времени жизни и владения. Некоторые на этом ломаются, но тем, кто смог пере...
🤔3
Ты не один
https://news.ycombinator.com/item?id=33347834
https://news.ycombinator.com/item?id=33347834
FWIW I personally found Rust the least-painful language, but that may well be confirming my pre-established biases :)I just spammed lifetime specifiers in various places until it compiled
- The pain from Rust was one time where the compiler wanted me to specify a lifetime, and I didn’t understand, so
. I’ve been using Rust for acouple of years now and I still don’t really understand lifetimes
, but thankfully 99% of the time I can avoid them.#rust
❤2😁1🤯1
Очередная спец-олимпиада, но, на этот раз, немного более практичная: https://github.com/shish/rosettaboy. Эмулятор gameboy одинаково реализованный на нескольких языках.
Автор запускает на Mac+clang, я на WSL2+gcc
В целом - просто хотел сказать что если счёт не идёт на наносекунды, то разница в основных претендентах минимальная и можно писать на том что больше нравится. Аргументы о тормозящем GC часто тоже не особо рабочие
#bench #rust #nim #cpp
Автор запускает на Mac+clang, я на WSL2+gcc
В целом - просто хотел сказать что если счёт не идёт на наносекунды, то разница в основных претендентах минимальная и можно писать на том что больше нравится. Аргументы о тормозящем GC часто тоже не особо рабочие
#bench #rust #nim #cpp
Why is Rust println! slower than Java println?
https://reddit.com/r/rust/s/hXPNlrnZaQ
> I think, that javas println is optimized and rust isn't. The reason why rust is not, could be that it doesn't matter. Rust doesn't want to be a language that can print fast. It has other priorities
#rust
https://reddit.com/r/rust/s/hXPNlrnZaQ
> I think, that javas println is optimized and rust isn't. The reason why rust is not, could be that it doesn't matter. Rust doesn't want to be a language that can print fast. It has other priorities
#rust
😁9❤2😱1
inv2004 Dev Blog
Случайно удалось скачать 100 страниц данных с upwork. Так что можно проанализировать "нестыдные" технологии - за которые платят. Я исключил из выборки некоторые страны, так как они сильно демпингуют. Финальный список тегов, их количество, cредняя минимальная…
Совсем забыл про #rust - он 1/2 от Golang, и, хотя, поддерживается в основной криптой - неплохой результат
— added —-
А Kotlin на один пункт выше Rust'а
— added —-
А Kotlin на один пункт выше Rust'а
👍1
Радио-Т: Rust против Go
Хотя очень редко слушаю Радио-Т, но, мимо такого пройти не мог. В пятёрочке очень удивлялись почему я стою пол-часа с рукой у лица возле полки с дошираком, но, для этого был повод.
В этой теме участвуют трое ведущих, и, если, один из них изображает непонимание и скепсис, то кринж от прослушивания вызывали двое других, изображающих из себя типичных растоманов первой волны - не писав на расте чего-то больше hello-world, что очень видно по тому как они путаются в базовых вещах, они, даже до некой обиды на первого ведущего, доказывают то как всё правильно и хорошо при написании веба на расте. При том, перепрыгивая и путаясь в
В общем-то это больше смешно, но есть пару выводов, которые я сделал для себя:
1) Чем меньше я пишу на расте, тем меньше у меня осталось к нему раздражения, растоманы новой волны куда лучше понимают его проблемы и проблему его позиционирования и являются куда меньше фанатиками RIIR (rewrite it in rust)
2) Перестал слушать Радио-Т потому как их профессиональной областью является обзор макбуков, а если говорить про dev-ориентированное, то лучше заменить, или совместить, с чем-то другим
https://t.me/radio_t_podcast/218
#rust #golang #podcast
Хотя очень редко слушаю Радио-Т, но, мимо такого пройти не мог. В пятёрочке очень удивлялись почему я стою пол-часа с рукой у лица возле полки с дошираком, но, для этого был повод.
В этой теме участвуют трое ведущих, и, если, один из них изображает непонимание и скепсис, то кринж от прослушивания вызывали двое других, изображающих из себя типичных растоманов первой волны - не писав на расте чего-то больше hello-world, что очень видно по тому как они путаются в базовых вещах, они, даже до некой обиды на первого ведущего, доказывают то как всё правильно и хорошо при написании веба на расте. При том, перепрыгивая и путаясь в
Clone
, Box
, dyn
, макросах и подобном. Дальше - лучше, начинают спец-олимпиаду - смотреть бенчмарки. И происходит такое: смотрите, rust обгоняет go-echo на 10%, эти 10% - это же миллионы и миллиарды долларов - говорит один из них => раст экономит миллиарды. На что другой (скептикам проще - они просто смотрят цифры) говорит, вот есть же go-fiber, и он, о боже, обгоняет rust на 10%. Но, если это стоит миллионы, может быть стоило использовать этот fiber, который всё равно быстрее?В общем-то это больше смешно, но есть пару выводов, которые я сделал для себя:
1) Чем меньше я пишу на расте, тем меньше у меня осталось к нему раздражения, растоманы новой волны куда лучше понимают его проблемы и проблему его позиционирования и являются куда меньше фанатиками RIIR (rewrite it in rust)
2) Перестал слушать Радио-Т потому как их профессиональной областью является обзор макбуков, а если говорить про dev-ориентированное, то лучше заменить, или совместить, с чем-то другим
https://t.me/radio_t_podcast/218
#rust #golang #podcast
😁9👍5❤1👎1
Спецолимпиада. 1/3
Было много дел, но тут, как гром среди ясного неба, на форуме прозвучало "вот тут бенчат разные языки https://github.com/jinyus/related_post_gen". В глубине души, понимая весь бред таких бенчей, я всё же не смог устоять чтобы не зайти по ссылке и не запустить разок ... потом второй ... очнулся через пару часов
Стоит оговориться о бенче, он довольно тупой - с ходу стало понятно, что близко к k-nucleotide, который я когда-то писал на Rust: https://t.me/inv2004_dev_blog/24 - хеш на хеше и тд. В итоге простая замена на xxhash дала заметный, но недостаточный, прирост.
Кстати, стоит упомянуть любимый (только по работе, конечно) Go, который обогнал всех с большим запасом + один из первых показал мультитредовую версию, где тоже затащил себя на первое местно.
Поначалу, была мысль забить, но, случайно заметил как Rust Evangelism Strike Force очень активно шлют PR за PR'ом. Nim при этом, кажется, даже в десятку не попадал, хотя это уже была не черновая версия. "Что за дела", подумал я, и достал
...
#bench #rust #nim #go
Было много дел, но тут, как гром среди ясного неба, на форуме прозвучало "вот тут бенчат разные языки https://github.com/jinyus/related_post_gen". В глубине души, понимая весь бред таких бенчей, я всё же не смог устоять чтобы не зайти по ссылке и не запустить разок ... потом второй ... очнулся через пару часов
Стоит оговориться о бенче, он довольно тупой - с ходу стало понятно, что близко к k-nucleotide, который я когда-то писал на Rust: https://t.me/inv2004_dev_blog/24 - хеш на хеше и тд. В итоге простая замена на xxhash дала заметный, но недостаточный, прирост.
Кстати, стоит упомянуть любимый (только по работе, конечно) Go, который обогнал всех с большим запасом + один из первых показал мультитредовую версию, где тоже затащил себя на первое местно.
Поначалу, была мысль забить, но, случайно заметил как Rust Evangelism Strike Force очень активно шлют PR за PR'ом. Nim при этом, кажется, даже в десятку не попадал, хотя это уже была не черновая версия. "Что за дела", подумал я, и достал
valgrind
, который показал какой-то eqcopy
, занимающийся какими-то аллокациами.valgrind
конечно, крут, ещё бы - по сути единственный несемплирующий профилировщик, но стек в нём видно куда хуже чем в perf
. Покопавшись в сгенерированном коде на C (за что Nim и нравится, хотя многие считают недостатком), стало понятно что Nim копирует целый вектор при чтении, что, конечно, полный провал. Удивило почему []
из хеша не умеет одалживать данные по указателю. В прочем, удивление длилось не долго - никаких больших проблем с этим нет - просто забыли проставить всего одно слово - lent
. Поставил - полетело. Есть всё же польза от бенчей...
#bench #rust #nim #go
👍10
Спецолимпиада. 2/3
Показалось что дальше копать в этой функции особо некуда и, я перешёл к следующей - просто найти top5 максимальных значений. Вроде, куда проще, но, по факту, это очень значительно влияло на итоговый результат при практически одинаковом коде функции. Тут уже пришлось подключать штуку потяжелее - Godbolt, я не настолько упоролся, чтобы начинать там разбирать ассемблер, но, было видно, что в одном случае эта функция занимает ~100 строк на asm, а в другом ~200+. Это, конечно, не правило, но, часто, чем короче тем лучше.
Дальше хуже
Тут, я переключился на ноут, где установлен Arch, со всем свежим. Тут оказалось, что версия компилятора C имеет критическое значение для бенчей. На свежем, оказалось, всё ровно наоборот -
...
#bench #rust #nim
Показалось что дальше копать в этой функции особо некуда и, я перешёл к следующей - просто найти top5 максимальных значений. Вроде, куда проще, но, по факту, это очень значительно влияло на итоговый результат при практически одинаковом коде функции. Тут уже пришлось подключать штуку потяжелее - Godbolt, я не настолько упоролся, чтобы начинать там разбирать ассемблер, но, было видно, что в одном случае эта функция занимает ~100 строк на asm, а в другом ~200+. Это, конечно, не правило, но, часто, чем короче тем лучше.
Дальше хуже
-flto
, а потом и пробы gcc
или clang
. Казалось что clang
вырвался вперёд, потом, неожиданно, оказалось что можно сделать PGO (Profile-Guided Optimization.Тут, я переключился на ноут, где установлен Arch, со всем свежим. Тут оказалось, что версия компилятора C имеет критическое значение для бенчей. На свежем, оказалось, всё ровно наоборот -
clang
очень плох, но clang
с PGO - лучше всех, при этом свежий gcc
(без всяких PGO) всего где-то на ~процент хуже, чем clang с PGO. Дальше хуже - оказалось что PGO (он тоже семплирует что ли?) только с 50% вероятностью что-то там цепляет важное. В итоге, без каких-то вообще изменений получались сборки, которые работали попеременно то быстро, то медленно. Я не нашёл ничего лучше, чем собирать PGO статистику не один раз, а 10, но и это не гарантировало 100% попадания. Мне прислали хорошее видео про это, но довольно тяжело поверить что всё настолько рандомно собирается https://youtu.be/r-TLSBdHe1A...
#bench #rust #nim
YouTube
"Performance Matters" by Emery Berger
Performance clearly matters to users. For example, the most common software update on the AppStore is "Bug fixes and performance enhancements." Now that Moore's Law has ended, programmers have to work hard to get high performance for their applications. But…
👍4
Спецолимпиада. 3/3
Итого - на ноуте
Но, написать я хотел не об этом.
А о том, что, пожалуй, из всего большого IT, эта область почему-то до сих пор вызывает интерес у меня. И, хотя, у меня нет желания лезть в embedded, и моё знание Asm довольно слабо, Но, и профилирование Clickhouse, и billion-taxi-rides, и оптимизация запросов, и много чего ещё включая любые рабочие задачи когда надо что-то ускорить - всегда вызывали живой интерес. Думаю, вот может, раз всё равно это нравится, то углубиться в эту тему. Но, опять же, не очень понятно в какую именно и есть ли вообще такая профессия с IT.
Буду благодарен любым рекомендациям, что почитать про это.
#bench #rust #nim
Итого - на ноуте
AMD 5650U
- Nim обошёл Rust, это, кстати, в -d:release
. Ведь есть еще -d:danger
который не такой уж и опасный на самом деле - для бенчей точно ок. На десктопе i5-12600
- Rust впереди на какую-то долю процента. Почему так - пока сказать не могу, может из-за overflowChecks.Но, написать я хотел не об этом.
А о том, что, пожалуй, из всего большого IT, эта область почему-то до сих пор вызывает интерес у меня. И, хотя, у меня нет желания лезть в embedded, и моё знание Asm довольно слабо, Но, и профилирование Clickhouse, и billion-taxi-rides, и оптимизация запросов, и много чего ещё включая любые рабочие задачи когда надо что-то ускорить - всегда вызывали живой интерес. Думаю, вот может, раз всё равно это нравится, то углубиться в эту тему. Но, опять же, не очень понятно в какую именно и есть ли вообще такая профессия с IT.
Буду благодарен любым рекомендациям, что почитать про это.
#bench #rust #nim
👍8🔥1
Так-то, на самом деле, не выглядит слишком заумным, кроме специфичного растовского
https://t.me/inv2004_dev_blog/28
#rust #компьютерный_юмор
Pin<>
, при попытке сделать websocket в actix было куда страшнее:Хотел было переехать на web-sockets, и тут, actix-web, казавшийся нормальным в качестве http показал, что структура для ws должна делаться так: Client<SinkWrite<Message, SplitSink<Framed<T, Codec>, Message>>>
https://t.me/inv2004_dev_blog/28
#rust #компьютерный_юмор
😁7👎2🤡1
Несложно подсчитать, что через 10 лет он сможет победить в категории "язык, на котором я бы хотел работать" в 16й раз
#rust
#rust
😁10👍1