Pull to refresh
225
0
Акиньшин Андрей @DreamWalker

Performance Engineer at JetBrains

Send message
Нет. ASM даже близко не позволит делать то же самое в коде.
Более того, сегодня он и по скорости проиграет плюсовому коду.

Да ладно! Согласен, кода получится в 600 раз больше, человекочасов уйдёт в 600 раз больше, придётся написать код под каждую железку, но в итоге можно получить более производительное решение. Взять, к примеру KolibriOS. Дистрибутив влезает на дискету, для запуска нужно 8 MB оперативы. Имеются драйверы, браузер, графический редактор, игры и ещё куча всякой всячины. Как считаете, отчего авторы взяли для написания ядра FASM, а не C++? Сможете ли вы написать аналог KolibriOS на плюсах, чтобы он работал быстрее и жрал меньше памяти?

В теории все супер, в реальной практике оба преимущества срабатывают лишь наполовину

Ок, если плюсы так хороши, то отчего же управляемые языки (C# и Java) отгрызли себе такой кусок рынка? Почему бы всем и всё не писать на плюсах? Моё мнение такое: управляемый подход сокращает время на разработку, снижает её стоимость, не даёт делать многих тупых багов. А вы как думаете?
Плюсы позволяют делать все то же самое что си шарп, плюс многое другое.

А ASM позволит мне делать ещё больше.
Тут скорее вопрос в дефолтном подходе и общей идеологии. C# сделан так, что случайно выстрелить себе в ногу было намного сложнее.
Моя основная мысль: программисту сложно сделать ошибку на C# в среднестатистическом коде по неосмотрительности или забывчивости. Половину стандартных ошибок запрещает делать компилятор — программа просто не будет скомпилирована. А если компиляция пройдёт успешно, то другая половина ошибок будет проверена в рантайме средой исполнения. Например, C#-программу практически нереально атаковать через переполнение буфера: если вы забыли проверить размерность массива, то .NET сделает это за вас. Да, приходится немножко платить за это общей производительностью, но это маленькая цена за то, что уходит намного меньше времени на продумывание низкоуровневых нюансов.
По поводу строгости. Если вы хорошо знаете платформу, то у вас есть возможность написать крутой и быстрый код. Тот же unsafe позволит вам конкурировать по скорости с плюсовыми приложениями. Но при этом нужно чертовски хорошо понимать происходящее. В CLR специально сделали ряд уступок по скорости, чтобы при желании и достаточном уровне знаний можно было писать очень клёвые штуки.
По поводу PVS-Studio. Мне доводилось встречаться с Андреем (автором постов) лично. И я спросил у него: а нет ли планов сделать подобный анализатор для C#. Он мне ответил, что это абсолютно бессмысленно, т. к. C# компилятор уже делает большую часть проверок. От себя добавлю, что скоро у нас появится Roslyn, который позволит писать крутые высокооуровневые проверки кода, которые сделают количество ошибок ещё меньше. Для примера посмотрите недавний пост Сергея Теплякова: Анализатор исключений на базе Roslyn-а.
Почитайте посты Andrey2008 про статический анализ крупных плюсовых проектов. То ли везде изначально плохой код, то ли везде совсем новички, то ли C# действительно просто не позволяет делать многих ошибок.
Это не лень, а естественное желание сосредоточиться на архитектуре, алгоритмах и бизнес-логике вместо того, чтобы тратить кучу времени на работу с низкоуровневыми проблемами.
я верю, что каким-то волшебным макаром можно вызвать такую функцию, подсунув ей не строку. Но как именно?

Тут нужно понимать, что вся безопасность типов в .NET работает на высоком уровне. Т. е. она сама по себе не должна ломаться, если кто-то не начнёт её специально ломать. Если у нас есть full trust, то мы можем в память писать вообще что угодно, никакой безопасности при этом никто не гарантирует. Если при этом плохо знать структуру .NET-овских объектов, то рантайм начнёт тошнить во все стороны, unspecified behavior будет в каждой строчке. В нормальном коде такое встречается крайне редко.
Полезной информации больше по сравнению с первой частью статьи, но ответа на главный вопрос всё ещё нет: как сделать так, чтобы ноги-то целыми остались? Заголовок статьи вселят надежду узнать не только «Кто виноват?», но и «Что делать?». Общая идея понятна: инвариант стандартных типов может быть испорчен. Не хватает:
  • Реального примера приложения, в котором по недосмотру может возникнуть такая проблема (в то время, как хорошие программисты на С/С++ (мне хочется верить) пользуются статическими анализаторами и ошибок вида if (i = 1) не возникает).
  • Как такую ситуацию опознать, найти проблему и решить её.
Мораль должна быть другой. Увы, иногда требования по производительности не дадут отказаться от unsafe. Просто в эти моменты нужно быть предельно внимательным.
Отдельно нужно писать гайды по использованию, а Class Reference documentation имеет смысл писать в коде: отпадает сложность синхронизации кода и документации + лёгкий доступ к информации из IDE.
Странный у вас способ себе в ногу стрелять. Вполне очевидно, что можно «испортить» внутреннее представление многих .NET-типов, после чего программа будет вести себя плохо. Что касается P/Invoke, то тут нужно разговаривать именно о неуправляемом коде и ошибках в нём, а не о сайд-эффектах после возвращения в управляемое окружение. Я считаю, что вы не с того конца обсуждение начали, морали нет. Если бы было что-нибудь в духе «В коде на С++ легко сделать вот такую ошибку, после чего при использовании P/Invoke из .NET могут быть такие-то проблемы; поступайте так-то, проверяйте то-то, не забывайте писать вот такие-то тесты», то пользы от статьи было бы намного больше.
Мы делаем следующим образом: в настройках нужных сборок ставится галочка «XML documentation file». Далее первращаем warnings в errors. Profit: если кто-то не прописал xml-документацию для публичной сущности, то код просто не будет компилироваться.
В AnyCPU под 64-битной осью оптимизация не срабатывает,

А галочка «Prefer 32 bit» не стоит

по причине того, что она не гарантируется

Ну а как её можно гарантировать? Там же пару байт поменяешь, так TCO станет ухудшать код или вовсе станет невозможна. Подвергать оптимизации метод нужно только тогда, когда он отвечает ряду специфических условий, за определение которых и должен отвечать JIT. А вот насколько хорошо он это делает — другой вопрос. В общем, я займусь на днях исследованием.
Очень интересная тема. Постараюсь в ближайшее время заняться исследованием. Я свято верю, что RyuJIT должен оптимизировать хвостовую рекурсию. Если не умеет, то я буду грустить. По поводу стектрейса тоже интересный вопрос: если .NET умеет делать правильный StackTrace, то я плохо представляю как он это делает. Кстати говоря, в Java по этой причине от оптимизации отказались (StackTrace потеряется, это плохо, пусть лучше у нас всё будет работать медленно). У меня есть подозрение, что дело обстоит так: в Debug оптимизация не применяется и StackTrace считается правильно, а в Release ситуация скорее всего должна быть аналогична ситуации с инлайнингом функций — там же тоже по сути стек вызовов портится.
В инструкции по созданию уроков предполагается использование Bitbucket. Скажите, планируется ли интеграция с GitHub?
Радует, что C# 6 проектировали адекватные люди =) Мне было бы очень грустно, если бы выбрали вариант с одним вопросиком.
Нет. Если ContactPerson равно null, то выражение vendor?.ContactPerson.HomeAddress упадёт.
Ну как-то грустно вместо родной системы событий .NET городить рядом ещё одну. Хотелось бы найти более нормальный способ решить проблему.
Ок, буду пробовать снова.
Почему никто не обращает на значок «Перевод»? Все примеры предоставлены Билом Вагнером. От себя замечу, что носят они демонстративный характер: чтобы в несколько строк показать общую идею.
Ну, во-первых, это не я туда же, это пост Била Вагнера. С вашим комментарием согласен, но есть два вопроса:
1. А как надо делать? Я так и не придумал более безопасного способа события вызывать.
2. А у вас есть рабочий минимальный пример, в котором подобная проблема возникает? Я в своё время пытался воспроизвести описанную проблему, но у меня так ничего и не получилось.

Information

Rating
Does not participate
Works in
Registered
Activity