суббота, 19 ноября 2022 г.

[prog.flame;humour] А ведь на самом деле интересно где же доказательства, что .NET и Java с GC лучше, чем Rust?

Этот вопрос я впервые озвучил в Facebook-е четыре года назад. Прошло столько времени, а он, как мне кажется, все еще остается актуальным.

Вот, кстати, вспомнился еще один момент, который забавляет, когда Rust начинают противопоставлять Java и .NET-у.

Ведь в Rust-е же, по сути, такая же система управления памятью, как и в C++. Есть автоматическая память. Есть динамическая. В динамической есть аналог unique_ptr (Box), есть аналог shared_ptr (Rc, Arc).

Да, Rust следит за тем, чтобы вы корректно работали со своей памятью. Но ведь система не меняется. Либо ограниченное скоупом время жизни (автоматические переменные, Box), либо подсчет ссылок (Rc, Arc).

Но где же аргументы со стороны языков с GC о том, что подсчет ссылок -- это удар по производительности? Где убедительные бенчмарки, которые показывают, что стоимость аллокации в языке с GC -- это всего лишь инкремент одного указателя на вершину хипа? Где упоминание такой фундаментальной проблемы, как фрагментация памяти (которой, как все знают, подвержены поголовно все программы на C++)? Где напоминание о таком волшебном средстве, как compacting GC?

Где, где все те срачи, в которых сторонники Java и C# так яростно убеждали нас, что GC гораздо лучше для управления памятью, чем ручная работа? И не только с точки зрения безопасности. Но и с точки зрения производительности.

А?

10 комментариев:

Stanislav Mischenko комментирует...

А разве кто-то когда-то утверждал, что GC лучше, чем подсчёт ссылок? Просто два разных способа автоматического управления памятью, оба живут и здравствуют кстати. Весь яблочный софт живёт на подсчёте ссылок, если что. Или я что-то упустил?

> Но где же аргументы со стороны языков с GC о том, что подсчет ссылок -- это удар по производительности?
Постоянные запуски GC тоже влияют на производительность. Они могут быть отложенными, но тем не менее. Если GC "не слишком умён", то у вас просто стопорится всё приложение, пока он не закончит. Такие "тупые" GC были на первых Андроидах. Сейчас они либо "поумнели", либо на устройствах стало больше памяти. Кстати, GC "любят", когда памяти моного, подсчёту ссылок вот всё равно. Так что, если вам в руки когда-нибудь попадётся какое-нибудь тормозящее устройство с Андроидом внутри, то теперь вы знаете причину тормозов ;)

> Где упоминание такой фундаментальной проблемы, как фрагментация памяти
Я думал, что сейчас эта проблема решается на уровне операционной системы. Она там постоянно, что-то перекидывает туда сюда, сжимает память, свопит.

eao197 комментирует...

> А разве кто-то когда-то утверждал, что GC лучше, чем подсчёт ссылок?

В свое время на том же RSDN-е были большие срачи "дотнетчики vs сиплюсплюсники". Там со стороны дотнетчиков были аргументы о том, что GC эффективнее, чем подсчет ссылок. Т.к. за подсчет ссылок платишь всегда (а если он на атомиках, то сейчас на многоядерных процессорах это дорого), тогда как GC срабатывает изредка и там не нужно платить за каждый инкремент/декремент ссылки.

Т.е. понятно, что все это зависит от сценариев, но подобная аргументация имела место быть году эдак в 2005-ом.

> Я думал, что сейчас эта проблема решается на уровне операционной системы.

Нет, это не решается на уровне ОС, т.к. фрагментация происходит в хипе приложения. Допустим, приложение запросило у ОС несколько страниц по 4096 байт. На каждой странице, допустим, половина места свободно, но за счет того, что там перемежаются блоки (занятые 32 байта, затем свободные 32 байта, потом опять занятые и т.д.). Т.е. вроде как по 2048 свободных байт на каждой странице есть, но вот выделить непрерывный блок длиной 2048 не получится без запроса новой страницы у ОС.

Вот это и есть фрагментация. В языках без GC, где пользователь манипулирует голыми указателями, эта проблема вряд ли решается. По крайней мере я сходу годное решение не могу припомнить.

Stanislav Mischenko комментирует...

На счёт фрагментации я понял. Просто, как мне кажется, сжатие памяти, которое есть в современных ОС, делает эту проблему не такой уж и страшной.

Alex комментирует...

по поводу дефрагментации - https://www.youtube.com/watch?v=XRAP3lBivYM&ab_channel=CppCon

Alex комментирует...

Да нет таких доказательств. По крайней мере мне они тоже не попадались. А все наезды на rust происходят единственно от нежелания иных разработчиков перейти из зоны привычного комфорта в зону, где надо посидеть, подумать, поразбираться. Проще ведь походя обговнячить.

eao197 комментирует...

@Alex:

> А все наезды на rust происходят единственно от нежелания иных разработчиков перейти из зоны привычного комфорта в зону, где надо посидеть, подумать, поразбираться.

Речь не про "обговнячить". Сейчас такие пожелания мне попадаются редко, а года четыре назад (когда этот вопрос и возник) регулярно встречались разговоры о том, как было бы хорошо использовать Rust вместо Java и C#. В качестве аргументации в пользу Rust приводились такие аргументы как отсутствие исключений и более явная передача ошибок, типизация с минимумом неявных преобразований типов и, как раз, отсутствие GC.

Причем я понимаю почему Rust может быть предпочтительнее чистого Си. Почему может быть предпочтительнее C++.

Но вот брать Rust вместо Java и C#?

При этом апологеты Java и C# много лет назад били себя пяткой в грудь доказывая C++никам насколько GC лучше и быстрее ручного управления памятью. Тогда GC был чуть ли не одним из флагов большей продуктивности и безопасности.

Логично было бы услышать такие же аргументы и при сравнении Rust с Java/C#. Но что-то не слышно.

Может быть сама идея применять Rust вместо Java/C#/Scala/Kotlin/Ceylon/F# таки умерла вполне себе естественным образом.

Alex комментирует...

Мне кажется, что сила java и других языков, что вы перечислили, в огромном количестве библиотек и фреймворков. А в производственной разработке, где действует принцип "черт с ней, с красотой - надо срочно, а лучше всего - вчера" это решающий фактор (я возьму тот же Spring + Spring MVC + Spring JPA и за пол-дня или за день слеплю работоспособное решение). А на rust я это же самое буду делать неделю. Да, на rust выйдет красивее (разумеется, imho), но увы - денежку плОтЮт не за это. Поэтому, в перспективе (лет минимум на 5) rust останется нишевым языком в реализации бизнесовых задач. А вот в системном программАзме - тут да, rust может себя проявить с блеском.
Повторюсь - это в значительной степени imho :)

eao197 комментирует...

@Alex

Ваше имхо плотно пересекается с моим имхо. Но даже когда Rust обрастет достаточным количеством инструментов, все равно останется тот фактор, что в Rust-е при программировании придется заморачиваться временами жизни и пр. низкоуровневыми деталями. Да, компилятор будет бить по рукам и косячить, как в C++, не получится. Но все равно это лишняя когнитивная нагрузка. От которой та же Java разработчиков освободила давным-давно.

Alex комментирует...

Солидарен

NN​ комментирует...

На самом-то деле если взглянуть куда идёт C# то легко заметить, что язык идёт как раз навстречу детерминированной работы с памятью.
Те же ref local, scoped local теперь, Span, упрощение работы с нативными фиксированными данными в памяти сборщика мусора.
Делается это не таким усложнением как в Rust , ведь есть сборщик мусора на подхвате.
Но позиция довольна ясна.
Сборщик мусора это дорого по сравнению со стеком :)

P.S.
Оставить тут комментарий стало сложной задачей.
Пока подтвердишь, что ты не робот с этими нереальными капчами, забудешь зачем зашёл :)