По моему опыту, скорость компиляции (инкрементальной) примерно одинаковая с С++. В работе с матрицами точно быстрее, где-то медленнее. В целом меня устраивает. В последней статье правильно указали про lto, в текущем проекте (верхний крейт 40kloc) инкрементальная компиляция 4-5 секунд, но если выключить lto то 1-1.5 секунды.
Не инкрементальную делаю наверное раз в пол года, когда обновляю компилятор, так что вообще не важно. И в последней статье как-раз про то, как её ускорить на билд сервере.
В BetterC, например. Это базовое требование для поддержки baremetal. Так что во всех ЯП с таким специалитетом.
Ну в С и С++ с этим как-то грустно, BetterC пока не пробовал.
Часть про Rust устарела процентов на 90. Вероятно и про остальные языки тоже. Например в конце вот этого очень длинного комментария описано реальное распространение Rust.
поменяли логику контроллера ссылок NLL (я умудрился в учебнике наступить на пример, как в статье) сломав 220 сторонних библиотек, которые как зависимости утащили за собой еще 2000.
Это неправда. Вы можете запустить те самые примеры из учебника даже на последнем компиляторе с edition="2015", и они будут работать. И библиотеки с edition="2015" можно вызывать из кода с edition="2024", будет (почти всегда) компилироваться и работать.
Нарушения обратной конечно совместимости были, но их очень мало, а не так как вы пытаетесь представить.
Например, недавно была новость про переписывание tmux на rust с 67к си кода на 87к строк unsafe rust кода, что определённо менее надёжно, чем tmux на си, который уже обкатан.
В той новости сам автор прямо пишет, что это альфа версия и хобби-проект:
Автор решения советует не использовать эту наработку в том случае, если кто-то не готов мириться с частыми сбоями.
Давайте все-таки сравнивать сравнимое. Подождем рабочий вариант, если он будет конечно.
Я и искал try_compile. А сейчас вы скинули совсем другие макросы. И вы в скриншоте вырезали строку "Please do not use this.", что как-бы намекает..
Есть куча документации прямо говорящей, что процедурные макросы компилируются в отдельные библиотеки, запускаются в отдельных процессах, в коде компилятора сами разбирайтесь зачем им сервера и клиенты макросов
Видимо вы не различаете декларативные и процедурные макросы. Последние по определению работают в отдельном процессе. Но вы писали про try_compile, который декларативный.
📦 postcompile: A macro for compiling Rust code at runtime. Useful for snapshot testing.
Вообще первый раз вижу, чтобы макрос делал fork, и нельзя ли было без него обойтись. В остальных 99% макросов никаких форков нет, и все в одном процессе.
А вы заявляете как будто любой макрос в Rust запускает что-то в отдельных процессах, что очевидная ложь. Вобщем продолжайте набрасывать дальше..
Аргументация в самой статье, о чем я и написал. Но в комментариях до моего первого поста суть статьи почти не обсуждали.
Менять же можно разными способами: добавляя новые ключи компиляции, внести в один из профилей безопасности и т.д. А старый функционал постепенно объявлять deprecated.
А теперь посмотрите, на мой первый пост. Минусующие (и вы тоже) даже не поняли, что я знаю как работает std::move по стандарту, и критикую именно стандарт. А заминусовали за то, что я как-бы не знаю стандарт.
Вместо того, чтобы паясничать, могли бы просто признать что были не правы про пропаганду. А вы не правы, как ни считай: ни по кол-ву крейтов, ни по кол-ву строк кода.
Ваше образование почему-то не позволило вам прочитать внимательно текст по вашей же ссылке:
Например, чтобы узнать методом Монте-Карло, какое в среднем будет расстояние между двумя случайными точками в круге, нужно взять координаты большого числа случайных пар точек в границах заданной окружности, для каждой пары вычислить расстояние, а потом для них посчитать среднее арифметическое.
4 штуки никак нельзя назвать большим числом. А вот 127,000 шт по моей ссылке уже большое число.
Кроме того, если в 4 крейтах будет 1/100000000000000000000000 строчек unsafe, по вашей статистике будет 100% случаев unsafe.
Встает вопрос, какие ещё допущения вам позволяет ваше математическое образование =)
P.S.
Вообще метод описан, если Вам мала выборка из 4х, берите большую. Будет выше точность.
С увеличением размера выборки до бесконечности (до фактического кол-ва крейтов) метод Монте-Карло превращается.. превращается в полноценную статистику, которую я уже приводил.
Интересно вы по выборке из 4 приложений отменили общую статистику по всем крейтам (127,000 шт). Большая разница (25% vs 81%) должна была вам тонко намекнуть, что 4 шт для статистики ничтожны.
Вот статистика по строчкам кода из 4 приложений еще куда ни шло, т.к. обеспечена статистически значимым числом: суммарно 109000 строк кода.
Итого 0,04% обоснованного (или 0,05% всего) unsafe кода - это я и называю "в прикладном коде unsafe практически не встречается". Делайте выводы математически правильно!
1) parity-db 20/24600 = 0.081% Внутри вызовы mmap и libс. Обоснованно. Еще 3 transmute, на первый взгляд можно и без них. 2) tabiew 11/7252 = 0,15% Всё в тестах, и абсолютно не нужно. Можно использовать static_cell или атомарные переменные. 3) xi-editor 30/29356 = 0.11% sse, avx, libc - какие-то оптимизации. Еще 2 не нужных str::from_utf8_unchecked.
4) poem 0/47700 = 0% Если выкинуть ненужные (на мой взгляд) unsafe, выйдет (17+28)/(24600+7252+29356+47700) = 0.04% В 2 из 4 проектах можно обойтись без unsafe точно.
P.S. mmap очевидно нужен, c libc, sse и avx я не разбирался, тут уже нужно много времени потратить.
As of May 2024, there are about 145,000 crates; of which, approximately 127,000 contain significant code. Of those 127,000 crates, 24,362 make use of the unsafe keyword, which is 19.11% of all crates. And 34.35% make a direct function call into another crate that uses the unsafe keyword. 6 Nearly 20% of all crates have at least one instance of the unsafe keyword, a non-trivial number.
Most of these Unsafe Rust uses are calls into existing third-party non-Rust language code or libraries, such as C or C++. In fact, the crate with the most uses of the unsafe keyword is the Windows crate 7, which allows Rust developers to call into various Windows APIs.
Примерно 81% крейтов не содержат ни одной строчки unsafe. А среди остальных большинство - это FFI.
Теперь ваша очередь доказывать про пропаганду. Надеюсь получить аргументированный ответ.
Посмотрел. Похоже, что его транслировали из C в Rust (например этим), и потом добились того чтобы компилировался.
Я делаю такой вывод из того, что внутри написана реализация memset, memchr и юникода (лол). Так что ваш пример - это антипример.
P.S. Вот пример +- большого проекта (https://github.com/picodata/picodata), изначально написанного на Rust. На 112kloc Rust кода 238 строк unsafe (0.2%). Из них около 80% это плагин к tarantool, т.к. обращения к ffi.
Но restrict по умолчанию только в safe Rust. А в unsafe мы оказываемся ближе к С (но не на его уровне), и можно писать код на указателях, главное при переходе снова к ссылкам соблюдать ограничение restrict.
На практике за этим надо следить разработчикам библиотек, которые что-то оптимизируют через unsafe и указатели, а в прикладном коде unsafe практически не встречается.
А вы точно прочитали статью? В конце раздела На сцене появляется C++11 ровно один указатель, и можно было бы заменить на std::string без изменения сути примера.
А суть в том, что на повторный std::move компилятор не выдает ошибку (и даже варнинг), и нужно много приседать, чтобы компилятор что-то заметил. Ито это не гарантируется.
"давайте рассыпем по коду сырых указателей да наворотим дикой дичи в стиле pure C".
По моему опыту, скорость компиляции (инкрементальной) примерно одинаковая с С++. В работе с матрицами точно быстрее, где-то медленнее. В целом меня устраивает.
В последней статье правильно указали про lto, в текущем проекте (верхний крейт 40kloc) инкрементальная компиляция 4-5 секунд, но если выключить lto то 1-1.5 секунды.
Не инкрементальную делаю наверное раз в пол года, когда обновляю компилятор, так что вообще не важно. И в последней статье как-раз про то, как её ускорить на билд сервере.
Ну в С и С++ с этим как-то грустно, BetterC пока не пробовал.
Согласен.
Просто я не вижу смысл обсуждать альфа-версии софта (давно известного), портированные с других языков.
Часть про Rust устарела процентов на 90. Вероятно и про остальные языки тоже.
Например в конце вот этого очень длинного комментария описано реальное распространение Rust.
Это неправда. Вы можете запустить те самые примеры из учебника даже на последнем компиляторе с edition="2015", и они будут работать. И библиотеки с edition="2015" можно вызывать из кода с edition="2024", будет (почти всегда) компилироваться и работать.
Нарушения обратной конечно совместимости были, но их очень мало, а не так как вы пытаетесь представить.
Перенесли большие куски кода из std в core и alloc. Скажите, в каком языке вы сможете пользоваться большей частью std без рантайма и даже без кучи?
В той новости сам автор прямо пишет, что это альфа версия и хобби-проект:
Давайте все-таки сравнивать сравнимое. Подождем рабочий вариант, если он будет конечно.
Вы написали
Я и искал try_compile. А сейчас вы скинули совсем другие макросы. И вы в скриншоте вырезали строку "Please do not use this.", что как-бы намекает..
Видимо вы не различаете декларативные и процедурные макросы. Последние по определению работают в отдельном процессе. Но вы писали про try_compile, который декларативный.
Этот макрос часть проекта https://github.com/scufflecloud/scuffle, нужен им для тестирования:
Вообще первый раз вижу, чтобы макрос делал fork, и нельзя ли было без него обойтись. В остальных 99% макросов никаких форков нет, и все в одном процессе.
А вы заявляете как будто любой макрос в Rust запускает что-то в отдельных процессах, что очевидная ложь. Вобщем продолжайте набрасывать дальше..
Аргументация в самой статье, о чем я и написал. Но в комментариях до моего первого поста суть статьи почти не обсуждали.
Менять же можно разными способами: добавляя новые ключи компиляции, внести в один из профилей безопасности и т.д. А старый функционал постепенно объявлять deprecated.
А теперь посмотрите, на мой первый пост. Минусующие (и вы тоже) даже не поняли, что я знаю как работает std::move по стандарту, и критикую именно стандарт. А заминусовали за то, что я как-бы не знаю стандарт.
Вместо того, чтобы паясничать, могли бы просто признать что были не правы про пропаганду. А вы не правы, как ни считай: ни по кол-ву крейтов, ни по кол-ву строк кода.
Итак?
Ваше образование почему-то не позволило вам прочитать внимательно текст по вашей же ссылке:
4 штуки никак нельзя назвать большим числом. А вот 127,000 шт по моей ссылке уже большое число.
Кроме того, если в 4 крейтах будет 1/100000000000000000000000 строчек unsafe, по вашей статистике будет 100% случаев unsafe.
Встает вопрос, какие ещё допущения вам позволяет ваше математическое образование =)
P.S.
С увеличением размера выборки до бесконечности (до фактического кол-ва крейтов) метод Монте-Карло превращается.. превращается в полноценную статистику, которую я уже приводил.
Интересно вы по выборке из 4 приложений отменили общую статистику по всем крейтам (127,000 шт). Большая разница (25% vs 81%) должна была вам тонко намекнуть, что 4 шт для статистики ничтожны.
Вот статистика по строчкам кода из 4 приложений еще куда ни шло, т.к. обеспечена статистически значимым числом: суммарно 109000 строк кода.
Итого 0,04% обоснованного (или 0,05% всего) unsafe кода - это я и называю "в прикладном коде unsafe практически не встречается". Делайте выводы математически правильно!
Господа минусующие, не могли бы вы аргументировать свою позицию?
Куда же вы пропали? Прошло уже 3 дня, на хабре вы бываете регулярно..
Я все еще жду от вас аргументации про пропаганду. Свой тезис я доказал общей статистикой, и вашим способом, по вашим же ссылкам.
Надеюсь на аргументированный ответ (но надежды уже тают..)
1) parity-db 20/24600 = 0.081%
Внутри вызовы mmap и libс. Обоснованно.
Еще 3 transmute, на первый взгляд можно и без них.
2) tabiew 11/7252 = 0,15%
Всё в тестах, и абсолютно не нужно. Можно использовать static_cell или атомарные переменные.
3) xi-editor 30/29356 = 0.11%
sse, avx, libc - какие-то оптимизации.
Еще 2 не нужных str::from_utf8_unchecked.
4) poem 0/47700 = 0%
Если выкинуть ненужные (на мой взгляд) unsafe, выйдет (17+28)/(24600+7252+29356+47700) = 0.04%
В 2 из 4 проектах можно обойтись без unsafe точно.
P.S. mmap очевидно нужен, c libc, sse и avx я не разбирался, тут уже нужно много времени потратить.
Легко. Цитирую:
Примерно 81% крейтов не содержат ни одной строчки unsafe. А среди остальных большинство - это FFI.
Теперь ваша очередь доказывать про пропаганду. Надеюсь получить аргументированный ответ.
Как и ожидалось, фразу про пропаганду вам подкрепить нечем.
Неужели так сложно сказать "я погорячился / я ошибся"?
Я вас прошу доказать вот эти ваши слова:
Потому что вы широко заявляете про пропаганду, но как пример приводите маленький проект, и обобщаете его на все проекты на Rust.
А я вам привел большой контрпример на 112kloc. Теперь, если вы стоите на своем, докажите на нескольких (больших) проектах.
Посмотрел. Похоже, что его транслировали из C в Rust (например этим), и потом добились того чтобы компилировался.
Я делаю такой вывод из того, что внутри написана реализация memset, memchr и юникода (лол). Так что ваш пример - это антипример.
P.S. Вот пример +- большого проекта (https://github.com/picodata/picodata), изначально написанного на Rust. На 112kloc Rust кода 238 строк unsafe (0.2%). Из них около 80% это плагин к tarantool, т.к. обращения к ffi.
Но restrict по умолчанию только в safe Rust. А в unsafe мы оказываемся ближе к С (но не на его уровне), и можно писать код на указателях, главное при переходе снова к ссылкам соблюдать ограничение restrict.
На практике за этим надо следить разработчикам библиотек, которые что-то оптимизируют через unsafe и указатели, а в прикладном коде unsafe практически не встречается.
Я считаю что это ошибка дизайна стандарта, и автор статьи тоже пытается это показать на примерах.
Причем не могу придумать ситуацию, где бы это было полезно. А значит можно было бы и поменять в новых версиях стандарта.
А вы точно прочитали статью? В конце раздела На сцене появляется C++11 ровно один указатель, и можно было бы заменить на std::string без изменения сути примера.
А суть в том, что на повторный std::move компилятор не выдает ошибку (и даже варнинг), и нужно много приседать, чтобы компилятор что-то заметил. Ито это не гарантируется.
Статью не читали, но осуждаете да?