Ну с электромобилями отличный пример, только в обратную сторону. Евродурачки фейкали-фейкали, насиловали-насиловали здравый смысл директивами, и добились только того, что автопроизводители потерпели гигантские убытки, а директивами теперь придётся подтереться. Так обычно и бывает, если кто-то просто врет без оглядки на реальные экономические и технические аспекты вопроса.
Все ещё хуже. Если бы этот калькулятор всегда выдавал 159, к этому ещё можно было бы приспособиться. Но он иногда выдаёт 159, иногда 9, а иногда 0. В общем, чтобы им пользоваться, ты должен все равно заранее посчитать, сколько должно получиться, и проверять за ним. Такое себе удовольствие.
Ну, такие на своём месте только в конторах, зарабатывающих очковтирательством (надуванием кокопеталезации на over 9000% за счёт хайповых на данный момент вбросов). Пока это нужно - да, такие на своём месте. Но работать работу, отвечать за свои слова и озвученные сроки такие не могут ("Что я до этого говорил, та это шутка была!", бгг). А этот ещё и руководство подставил своими завиральными идеями, бгг.
Гражданин создал себе репутацию трындобола на ровном месте, поздравляю. Причём, что характерно, раст, ИИ, прямо весь флеш-рояль тупой пропаганды и хайпа, бгг. Удачи с поиском новой работы в перспективе. Интернет все помнит.
У Хрома на 20млн строк С++/С около 1250 RCE было, если верить Gemini.
Даже если ей верить, то это получается 1 RCE на 16 тысяч строк кода, все-таки сразу уже на порядок разница. Дальше, вот например описание буквально недавней уязвимости, потенциально сводимой к RCE (от вчерашнего числа). Вся суть его в том, что в реализации сборщика мусора была допущена логическая ошибка. Даже если реализацию этого сборщика мусора переписать на расте, это ничего не даст, потому что борроу чекер раста тут будет бесполезен, а такого рода вещи будут написаны unsafe через unsafe погоняет unsafe, иначе никак. Сборщики мусора имеют много дел с разнообразными графами (и GC JS-движка хромиума не исключение), а это как раз одна из ахиллесовых пят раста - см. недавнюю уязвимость в реализации связного списка на расте, кстати. Вообще любая сколько-нибудь сложная структура из объектов со множественными связями - и все, примитивный борроу чекер раста вам не помощник, добро пожаловать в написание unsafe кода.
Причем забавно, что Хартман поспешил заявить, что это якобы "не эксплуатируемая" уязвимость, в чем лично я сильно сомневаюсь. Уязвимости, связанные с гонками, обычно труднее эксплуатировать, это так, но зачастую это все-таки вполне возможно. В любом случае, доверять словам по-любому ангажированного гражданина я бы не спешил.
В коде на C++ в среднем было под 1000 ошибок доступа к памяти / млн. строк.
В свое время, когда я читал эту статейку, мне эта "статистика" очень глаз-то резанула, это одна ошибка доступа к памяти на 1000 строк. По моему личному опыту это даже не близко - я бы сказал, разница на пару порядков как минимум. Впрочем, пропаганда раста идет весьма оголтело, чего стоит хотя бы обсуждаемый высер от "ведущего инженера микрософт", на фоне которого высер от гугла даже как-то скромно выглядит, бгг.
технический директор Azure Марк Руссинович запретил разработчикам начинать новые проекты на C/C++
По ссылке на слове "запретил": "запущен проект по включению разработки драйверов для Windows на Rust, разработчики проекта пояснили, что этот репозиторий всё ещё находится на ранней стадии разработки и пока не рекомендуется использовать его для коммерческого использования". Новость тоже ИИ писал?
Ну и да, новость - классическая шняга про Ходжу, шаха и ИИ ишака. Плохо только, что "к 2030 году" про нее никто не вспомнит, никаких выводов сделано опять не будет, появятся новые "амбициозные задачи", от очередных "ведущих инженеров", решивших продвинуться здесь и сейчас по принципу "казаться а не быть".
P.S. Вообще конечно удивительно, что "инженеры" сейчас настолько деградировали, что позволяют себе нести подобную шнягу. Так и представляю себе этого Галена Ханта ближе к 2030 году в поисках новой работы:
- За что вы отвечали в Microsoft? - За перевод кодовой базы на Rust. - А-а, так это вы тот идиот, который обещал миллион строк в месяц с ИИ и одним инженером? Пошел нах...
Ну, а считать производительность на вырожденных случаях в дебаге несколько странное занятие.
Меня главным образом интересовало, сколько лукапов делает реализация через эти Entry в расте, и было две альтернативы - сидеть с бутылкой и разбирать внутренности Entry или по-быстрому попробовать грубо оценить через тайминги на вырожденном случае. Ну хотя внутренности все равно пришлось разбирать.
И не понимаю почему or_insert триггерит пессимизацию производительности в дебаге учитывая, что там обычный матч по собственному состоянию.
Ну так-то в данном конкретном месте матч, да, но потом через десятые руки в hashbrown::hash_map вызывается вот такое:
impl<'a, T, A> VacantEntry<'a, T, A>
where
A: Allocator,
{
pub fn insert(self, value: T) -> OccupiedEntry<'a, T, A> {
let bucket = unsafe {
self.table
.raw
.insert_tagged_at_index(self.tag, self.index, value)
};
OccupiedEntry {
bucket,
table: self.table,
}
}
}
Т.е. VacantEntry запоминает внутри себя что-то типа индекса букета и вставляет там значение в этот букет. На беглый взгляд вообще выглядит не так плохо с точки зрения производительности, но с точки зрения переложения этого механизма на C++ выглядит не очень.
Можете попробовать сравнить cpp с rust и посмотреть будет ли там деградация на коллизиях.
В текущем C++ API деградации на коллизиях просто неоткуда взяться, так как после единственного лукапа при insert мы сразу получаем итератор, указывающий на конкретную прямо KV-пару, и все на этом, дальше работа идет просто с этой KV-парой напрямую. Можно вообще взять на нее ссылку сразу, никто не мешает. Там все ясно и понятно. У раста же многое зависит от качества реализации вот этой прослойки всей, нужно с бутылкой засесть и потеть, если хочешь разобраться, не факт что какие-нибудь умельцы чего-нибудь не пессимизируют потом... Ну и конечно тот факт что Entry пожирает всю мапу до конца своего лайфтайма, тоже мягко говоря, не очень удобно.
А вы уверены, что решается именно эта задача? Я вот сейчас не поленился, написал тест с вырожденной хеш-функцией, намеренно создающей коллизии. И что-то как только я комментирую часть .or_insert(i), так сразу время выполнения примерно вдвое падает. Ну прямо очень похоже на отдельный лукап на вставке. Да и с чисто технической стороны вопроса, из описания всех этих or_insert следует, что они выполняют полноценную операцию вставки, включая лукап. Иначе согласно этому API бы приходилось сначала всегда вставлять какой-то элемент в букет, если элемента с соответствующим ключом нет, а если or_insert не вызван, то приходилось бы его удалять при уничтожении экземпляра Entry, верно? А если вставляемый экземпляр невозможно создать со значениями "по умолчанию", как быть? Вопросы, вопросы...
P.S. Есть конечно вариант не вставлять "пустое" значение, а просто найти букет и держать его, но тогда получается, что ты не можешь найти Entry, потом что-нибудь сделать с map (скажем, вставить что-то или удалить), а потом сделать что-то с сохраненной Entry. В расте эта проблема "решается" тем что Entry "одалживает" map в свое полное распоряжение, и ты ничего не сможешь с этим map сделать, пока экземпляр Entry не уничтожится. Ну, тоже такое себе в приложении к C++.
Сейчас очень частая задача вида "если элемента с таким-то ключом еще нет в мапе, то вставить начальное значение, если он есть - то инкрементировать его на N" благодаря текущему API решается за один лукап. Продемонстрируйте, пожалуйста, как такая задача будет решаться за один лукап "по аналогии со ржавым" или "через какой-нибудь insert_or_update()", а то лично мне например непонятно, в чем состоит идея и как эта идея что-то реально улучшит, за исключением "перехода на опционалы ради перехода на опционалы".
Я программирую на расте и благодаря этой "лжи" даже не беспокоюсь о сегфолтах.
Любая проблема в unsafe коде раста (а если даже вы лично его не пишете, то в используемых вами разнообразных библиотеках его точно полно, как и в FFI-обертках к внешним библиотекам на других языках) может протечь куда угодно, и вы так же будете "неделями сидеть и искать, где какой-нибудь байт указателя перезаписывается", как афтар каментов выше пишет про C. А если настанет такой момент, когда забивать шуруп молотком "безопасного" раста больше будет нельзя по объективным причинам и вы решите написать более эффективный код, чем тот, что позволяет вам написать тупорылый борроу чекер, то вам придется писать собственный unsafe код, и вот тут вы окажетесь на минном поле в квадрате, потому что, как выше правильно написал другой афтар каментов, никто на самом деле точно не знает, что является или не является UB в unsafe подмножестве раста (в отличие от C где это худо-бедно описано в стандарте - да, кое-где можно придраться к "не совсем очевидным формулировкам", но тем не менее).
Ну я веду речь вообще-то про выбор между "написать самому или доверить LLM". LLM вряд ли принципиально лучше джуна или хитрожопого погромиста, а врать умеет даже, пожалуй, поубедительнее последнего. Впрочем, дело вкуса.
И вся прелесть LLM в том, что по идее она сама должна скомбинировать нечто подобное по вашему требованию (промпту).
Вот именно что "по идее". Сгенерированное все равно потом потребуется проверить как минимум на предмет полноты и адекватности, и результат проверки вас вполне может неприятно удивить.
Ну с электромобилями отличный пример, только в обратную сторону. Евродурачки фейкали-фейкали, насиловали-насиловали здравый смысл директивами, и добились только того, что автопроизводители потерпели гигантские убытки, а директивами теперь придётся подтереться. Так обычно и бывает, если кто-то просто врет без оглядки на реальные экономические и технические аспекты вопроса.
Все ещё хуже. Если бы этот калькулятор всегда выдавал 159, к этому ещё можно было бы приспособиться. Но он иногда выдаёт 159, иногда 9, а иногда 0. В общем, чтобы им пользоваться, ты должен все равно заранее посчитать, сколько должно получиться, и проверять за ним. Такое себе удовольствие.
Ну, такие на своём месте только в конторах, зарабатывающих очковтирательством (надуванием кокопеталезации на over 9000% за счёт хайповых на данный момент вбросов). Пока это нужно - да, такие на своём месте. Но работать работу, отвечать за свои слова и озвученные сроки такие не могут ("Что я до этого говорил, та это шутка была!", бгг). А этот ещё и руководство подставил своими завиральными идеями, бгг.
Гражданин создал себе репутацию трындобола на ровном месте, поздравляю. Причём, что характерно, раст, ИИ, прямо весь флеш-рояль тупой пропаганды и хайпа, бгг. Удачи с поиском новой работы в перспективе. Интернет все помнит.
Даже если ей верить, то это получается 1 RCE на 16 тысяч строк кода, все-таки сразу уже на порядок разница. Дальше, вот например описание буквально недавней уязвимости, потенциально сводимой к RCE (от вчерашнего числа). Вся суть его в том, что в реализации сборщика мусора была допущена логическая ошибка. Даже если реализацию этого сборщика мусора переписать на расте, это ничего не даст, потому что борроу чекер раста тут будет бесполезен, а такого рода вещи будут написаны unsafe через unsafe погоняет unsafe, иначе никак. Сборщики мусора имеют много дел с разнообразными графами (и GC JS-движка хромиума не исключение), а это как раз одна из ахиллесовых пят раста - см. недавнюю уязвимость в реализации связного списка на расте, кстати. Вообще любая сколько-нибудь сложная структура из объектов со множественными связями - и все, примитивный борроу чекер раста вам не помощник, добро пожаловать в написание unsafe кода.
Причем забавно, что Хартман поспешил заявить, что это якобы "не эксплуатируемая" уязвимость, в чем лично я сильно сомневаюсь. Уязвимости, связанные с гонками, обычно труднее эксплуатировать, это так, но зачастую это все-таки вполне возможно. В любом случае, доверять словам по-любому ангажированного гражданина я бы не спешил.
В свое время, когда я читал эту статейку, мне эта "статистика" очень глаз-то резанула, это одна ошибка доступа к памяти на 1000 строк. По моему личному опыту это даже не близко - я бы сказал, разница на пару порядков как минимум. Впрочем, пропаганда раста идет весьма оголтело, чего стоит хотя бы обсуждаемый высер от "ведущего инженера микрософт", на фоне которого высер от гугла даже как-то скромно выглядит, бгг.
Это классика, "A Brief History of the Windows Programming revolution".
Честно говоря, на плейграунде поведение у этого кода "несколько отличается":
Это он на собеседованиях будет рассказывать :)
В статье:
По ссылке на слове "запретил": "запущен проект по включению разработки драйверов для Windows на Rust, разработчики проекта пояснили, что этот репозиторий всё ещё находится на ранней стадии разработки и пока не рекомендуется использовать его для коммерческого использования". Новость тоже ИИ писал?
Ну и да, новость - классическая шняга про Ходжу, шаха и
ИИишака. Плохо только, что "к 2030 году" про нее никто не вспомнит, никаких выводов сделано опять не будет, появятся новые "амбициозные задачи", от очередных "ведущих инженеров", решивших продвинуться здесь и сейчас по принципу "казаться а не быть".P.S. Вообще конечно удивительно, что "инженеры" сейчас настолько деградировали, что позволяют себе нести подобную шнягу. Так и представляю себе этого Галена Ханта ближе к 2030 году в поисках новой работы:
- За что вы отвечали в Microsoft?
- За перевод кодовой базы на Rust.
- А-а, так это вы тот идиот, который обещал миллион строк в месяц с ИИ и одним инженером? Пошел нах...
Меня главным образом интересовало, сколько лукапов делает реализация через эти
Entryв расте, и было две альтернативы - сидеть с бутылкой и разбирать внутренностиEntryили по-быстрому попробовать грубо оценить через тайминги на вырожденном случае. Ну хотя внутренности все равно пришлось разбирать.Ну так-то в данном конкретном месте матч, да, но потом через десятые руки в
hashbrown::hash_mapвызывается вот такое:Т.е.
VacantEntryзапоминает внутри себя что-то типа индекса букета и вставляет там значение в этот букет. На беглый взгляд вообще выглядит не так плохо с точки зрения производительности, но с точки зрения переложения этого механизма на C++ выглядит не очень.В текущем C++ API деградации на коллизиях просто неоткуда взяться, так как после единственного лукапа при insert мы сразу получаем итератор, указывающий на конкретную прямо KV-пару, и все на этом, дальше работа идет просто с этой KV-парой напрямую. Можно вообще взять на нее ссылку сразу, никто не мешает. Там все ясно и понятно. У раста же многое зависит от качества реализации вот этой прослойки всей, нужно с бутылкой засесть и потеть, если хочешь разобраться, не факт что какие-нибудь умельцы чего-нибудь не пессимизируют потом... Ну и конечно тот факт что
Entryпожирает всю мапу до конца своего лайфтайма, тоже мягко говоря, не очень удобно.А вы уверены, что решается именно эта задача? Я вот сейчас не поленился, написал тест с вырожденной хеш-функцией, намеренно создающей коллизии. И что-то как только я комментирую часть
.or_insert(i), так сразу время выполнения примерно вдвое падает. Ну прямо очень похоже на отдельный лукап на вставке. Да и с чисто технической стороны вопроса, из описания всех этихor_insertследует, что они выполняют полноценную операцию вставки, включая лукап. Иначе согласно этому API бы приходилось сначала всегда вставлять какой-то элемент в букет, если элемента с соответствующим ключом нет, а еслиor_insertне вызван, то приходилось бы его удалять при уничтожении экземпляраEntry, верно? А если вставляемый экземпляр невозможно создать со значениями "по умолчанию", как быть? Вопросы, вопросы...P.S. Есть конечно вариант не вставлять "пустое" значение, а просто найти букет и держать его, но тогда получается, что ты не можешь найти
Entry, потом что-нибудь сделать сmap(скажем, вставить что-то или удалить), а потом сделать что-то с сохраненнойEntry. В расте эта проблема "решается" тем чтоEntry"одалживает"mapв свое полное распоряжение, и ты ничего не сможешь с этимmapсделать, пока экземплярEntryне уничтожится. Ну, тоже такое себе в приложении к C++.Сейчас очень частая задача вида "если элемента с таким-то ключом еще нет в мапе, то вставить начальное значение, если он есть - то инкрементировать его на N" благодаря текущему API решается за один лукап. Продемонстрируйте, пожалуйста, как такая задача будет решаться за один лукап "по аналогии со ржавым" или "через какой-нибудь
insert_or_update()", а то лично мне например непонятно, в чем состоит идея и как эта идея что-то реально улучшит, за исключением "перехода на опционалы ради перехода на опционалы".Каким образом? Там же итератор возвращается всегда, независимо от того, был уже этот элемент в контейнере или нет, в этом весь смысл такого API.
Любая проблема в unsafe коде раста (а если даже вы лично его не пишете, то в используемых вами разнообразных библиотеках его точно полно, как и в FFI-обертках к внешним библиотекам на других языках) может протечь куда угодно, и вы так же будете "неделями сидеть и искать, где какой-нибудь байт указателя перезаписывается", как афтар каментов выше пишет про C. А если настанет такой момент, когда забивать шуруп молотком "безопасного" раста больше будет нельзя по объективным причинам и вы решите написать более эффективный код, чем тот, что позволяет вам написать тупорылый борроу чекер, то вам придется писать собственный unsafe код, и вот тут вы окажетесь на минном поле в квадрате, потому что, как выше правильно написал другой афтар каментов, никто на самом деле точно не знает, что является или не является UB в unsafe подмножестве раста (в отличие от C где это худо-бедно описано в стандарте - да, кое-где можно придраться к "не совсем очевидным формулировкам", но тем не менее).
Поправил, не благодарите.
Ну я веду речь вообще-то про выбор между "написать самому или доверить LLM". LLM вряд ли принципиально лучше джуна или хитрожопого погромиста, а врать умеет даже, пожалуй, поубедительнее последнего. Впрочем, дело вкуса.
Вот именно что "по идее". Сгенерированное все равно потом потребуется проверить как минимум на предмет полноты и адекватности, и результат проверки вас вполне может неприятно удивить.