понедельник, 27 марта 2017 г.

[prog.flame] Rust-оманы зря пытаются продавать Rust С++никам, им бы поменять целевую аудиторию :)

Данный пост возник под впечатлением от двух недавних больших срачей на reddit-е на тему о том, почему Rust лучше C++: Have you used Rust? Do you prefer it over Modern C++? и Things I love about Rust while being a C++ programmer. А так же интересным ссылкам, которые проскочили в этих обсуждениях, например: вот (про некоторые проблемы Rust) или вот (специально для тех, кто верит, что безопасность Rust-а не имеет платы в run-time). Кроме шуток, срачи интересные, помимо обычного булшита (например, в очередной раз всплыл аргумент о том, как классно иметь возможность во время компиляции подключиться к СУБД, выкачать оттуда описание схемы данных и сгенерировать ORM) встречаются и прикольные примеры C++ граблей на ровном месте. Вот, скажем:

auto adjacently_added(auto array_view) {
  assert(size(array_view) > 1);
  return indices(size(array_view) - 1) |  // using range-v3
     transform([&](auto&& idx) { return array_view[i] + array_view[i+1]; });
}

Был еще отличный пример лучшей читабельности Rust-а в сравнении с C++:

fn apply(mut f: F, a: A) 
-> impl FnMut(&B) -> C // must still be `for<'r> impl FnMut(&'r B) -> C`, because that’s what filter requires
     where F: FnMut(B) -> G,  // must not be `for<'r> FnMut(&'r B) -> G`, because regular functions do not implement it
           G: FnMut(A) -> C,
           B: Copy, // for dereferencing
           A: Clone {
move |b| f(*b)(a.clone()) // this must do any bridging necessary to satisfy the requirements
}

В общем, если есть время и желание разобраться, чем же Rust лучше C++, то имеет смысл пройтись по этим ссылкам. Глядишь, кто-то и загорится желанием уйти с C++ на новый, гораздо более удобный и безопасный язык. Ну или не загорится ;)

Но вот у меня по ходу чтения всех аргументов "за" Rust возникло ощущение, что подобное я уже видел. Причем неоднократно.

Под "подобным" я имею в виду апелляцию к главному аргументу в пользу Rust-а: безопасности. Практически все сторонники Rust подчеркивают, что Rust безопасен. Или что он безопаснее, чем C++. Или что Rust спроектирован так, чтобы ставить безопасность во главу угла. И т.д., и т.п. Безопасность, безопаснее, безопасность, безопаснее и так без конца и перерыва.

Так вот, все эти разговоры про безопасность очень похожи на те разговоры, которые велись 20 лет назад в пользу Java. Java -- безопасный язык. Java безопаснее, чем C++. Java проектировалось с прицелом на безопасность. А потом место Java занял C#. А потом место C# занимали Python, Haskell, Erlang, Go. Теперь вот Rust. Кроме того, я настолько старый, что помню еще времена, когда Pascal и Delphi были более безопасными, чем C++.

Я не хочу сказать, что эти языки не отъедали нишу у C++. Отъедали и еще как. Правда, я думаю, что во многом это произошло потому, что в конце 80-х и в начале 90-х в виду отсутствия вменяемых альтернатив C++ использовался слишком уж широко. Так что вполне ожидаемо C++ вытесняли оттуда, где изначально требовалось что-то другое.

Однако, вытеснению C++ способствовало не только появление более безопасных и удобных в повседневном использовании альтернатив. Но и еще такой немаловажный фактор, как очень шустрый рост вычислительных мощностей. Железо дешевело, рабочая сила (т.е. программисты) -- дорожали. Поэтому вполне естественно, что ради сокращения сроков разработки в два раза можно было пойти на то, чтобы для работы программного продукта требовалось бы в пять раз более мощное железо. То, что Java работает внутри своей виртуальной машины (дополнительный слой абстракции, а значит и дополнительные расходы), да еще и со сборщиком мусора (требуется дополнительная память, опять же дополнительные расходы), никого не волновало. Т.к. мощность компьютеров росла постоянно, а стоимость этих самых компьютеров постоянно снижалась.

Еще более круто это все начало выглядеть лет 12-13 назад, когда Java и C# начали теснить заведомо более медленные динамически-типизированные языки: PHP, Python, Ruby, JavaScript, Erlang. Т.е. мощность компьютеров выросла настолько, что даже более серьезные накладные расходы динамически-типизированных языков по сравнению с Java, не говоря уже про разрыв в производительности и ресурсоемкости по сравнению с C++, не были сколько-нибудь серьезным препятствием. Главное было как можно быстрее выдать готовый результат. В скорости написания кода Java-разработчики выигрывали у C++ников, а Ruby-исты и Python-исты выигрывали у Java-разработчиков.

Но вот последние лет пять (плюс-минус пара лет) ситуация меняется. Как мне кажется, происходит две вещи:

  • во-первых, рост мощностей вычислительной техники значительно замедлился. Можно посмотреть на рынок ноутбуков, который с начала 2000-х развивался очень стремительно. Лет десять назад казалось, что пройдет немного времени и в самых младших моделях будет не менее 4GiB RAM и 4-х ядерный процессор. Но вот эти 10 лет прошли. Полно недорогих моделей, которые имеют всего 2GiB (два, Карл!) RAM и какой-нибудь дохленький Celeron или Atom в качестве процессора. И они раскупаются. Почему? Потому, что недорогие. На рынке смартфонов, хотя я за ним практически не слежу, ситуация похожая: топовые модели, конечно же развиваются, уже есть телефоны с 8-ю и 10-ю ядерными процессорами, с 3GiB RAM, а может даже и с 4GiB. Но при этом на рынке полно и более дешевых, а значит и более слабых моделей. Кроме того, чем круче становится начинка смарфонов, тем реже они обновляются, т.к. моральное устаревание происходит намного позже. Ну и, конечно же, облака. В которых провайдеры берут деньги за все, а одним из конкурентных преимуществ для хостера оказывается тарификация с точность до минуты. Пользователям облаков приходится внимательно следить, насколько эффективно расходуются ресурсы, за каждую минуту использования которых приходится платить. Что уж говорить про тех, у кого собственный немаленький парк серверов. Если у каких-нибудь Одноклассников одинадцать тысяч серверов, они вряд ли могут себе позволить не думать о ресурсоемкости своих решений;
  • во-вторых, когорта разработчиков, которые знают, что такое C, С++ и работа на реальном железе, а не в рамках уютненькой VM, за прошедшие 20 лет очень серьезно сократилась. Страшно подумать, но если кто-то из программистов начал свою карьеру в 2005-ом в качестве Ruby-On-Rails разработчика, то у него сейчас стаж работы уже 12 лет. Очень много по нынешним меркам. Но за эти 12 лет он вряд ли написал хотя бы строчку кода на языке, который бы компилировался в нативный код! Регулярно доводится встречать описание карьеры какого-нибудь докладчика или автора статьи, откуда выясняется, что человек занимается разработкой уже 15 лет, работал с Java, C#, JavaScript и Python. Но он не работал ни с C, ни c С++. Так откуда у него возьмется представление о том, что такое высокая эффективность и низкое потребление ресурсов? В общем, я это к тому, что когда у 90% разработчиков могут работать в лучшем случае только с Java или C#, то как созданные ими приложения будут конкурировать друг с другом по производительности и ресурсоемкости?

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

Видимо, из-за этого такой приличный успех у Go: прост, как Python, но в три раза быстрее, и гораздо менее прожорливее. Отсюда же и попадающиеся на глаза статьи о том, как пытаются разгонять приложения на Python-е. Или как пишут real-time и low-latency приложения на Java, превращая Java в подобие C (даже не в C++ с его шаблонами и дешевыми абстракциями). Ну еще бы: текущие инструменты не релевантны современным требованиям, а переходить на C++ -- не комильфо. Кто ж из бородатых хипстеров признается себе, что вместо подключения к Python-у еще одного хардкорного C-шного расширения имело бы смысл посмотреть в сторону давно существующего C++? С++ -- это же всем известное монстроподобное и ужасное говно мамонта, предназначенное только для отстрела ног и настолько сложное в изучении, что и всей жизни не хватит, чтобы выучить, как объявить ссылку на указатель на массив. И это речь еще про виртуальный деструктор не зашла :)

Другое дело Rust. Модный, молодежный, безопасный, функциональный (аффинные типы, паттерн-матчинг, функции высшего порядка, все дела), быстрый, с готовым менеджером зависимостей, встроенными средствами для тестирования, статического анализа и даже форматирования исходного текста в едином стиле! И все это совершенно бесплатно, без регистрации и SMS!

Пытаетесь выжать дополнительную тысячу запросов в секунду посредством asyncio в Python-е? Страдаете от задержек GC в Java? Устали от длительного времени компиляции и связанных с ленивостью просадок производительности в Haskell-е? Задолбала динамическая типизация в JavaScript и Ruby?

Попробуйте Rust!

Скорость C, мощность Haskell-я и расширяемость Nemerle. And last but not least: batteries included ;)


Шутки-шутками, но если бы Rust так же агрессивно противопоставляли Python-у, Ruby или Go, как Rust противопоставляют C++, то положительный эффект для Rust-а мог бы быть гораздо серьезнее. Ну и противопоставление Rust-а Java так же имело бы смысл. Понятное дело, что тем, кто использует Java гораздо важнее наличие IDE класса IDEA, нежели наличие иммутабельности, алгебраических типов данных и паттерн-матчинга. Но все-таки... Лично я бы предпочел делать real-time на Rust-е, а не на Java.

Комментариев нет: