Я разработчик на C ++ и C #. Я разрабатывал приложения на C # с момента первой беты .NET Framework, и у меня более 20 лет опыта в разработке приложений на C ++. Во-первых, код C # НИКОГДА не будет быстрее, чем приложение C ++, но я не буду подробно обсуждать управляемый код, его работу, уровень взаимодействия, внутреннюю структуру управления памятью, систему динамических типов и сборщик мусора. Тем не менее, позвольте мне продолжить, сказав, что все перечисленные критерии дают НЕПРАВИЛЬНЫЕ результаты.
Позвольте мне объяснить:
Первое, что нам нужно рассмотреть, - это JIT-компилятор для C # (.NET Framework 4). Теперь JIT создает собственный код для ЦП с использованием различных алгоритмов оптимизации (которые, как правило, более агрессивны, чем стандартный оптимизатор C ++, поставляемый с Visual Studio), а набор инструкций, используемый компилятором .NET JIT, является более точным отражением фактического ЦП. на машине, поэтому можно сделать определенные замены в машинном коде, чтобы уменьшить тактовые циклы и повысить частоту обращений в кеше конвейера ЦП, а также произвести дальнейшую оптимизацию гиперпоточности, такую как переупорядочение команд и улучшения, связанные с предсказанием ветвлений.
Это означает, что если вы не скомпилируете свое приложение C ++, используя правильные параметры для сборки RELEASE (не сборки DEBUG), то ваше приложение C ++ может работать медленнее, чем соответствующее приложение на основе C # или .NET. При указании свойств проекта в приложении C ++ убедитесь, что вы включили «полную оптимизацию» и «одобрение быстрого кода». Если у вас есть 64-битная машина, вы ДОЛЖНЫ указать, что в качестве целевой платформы необходимо создать x64, иначе ваш код будет выполняться через подуровень преобразования (WOW64), что существенно снизит производительность.
Как только вы выполните правильную оптимизацию в компиляторе, я получу 0,72 секунды для приложения C ++ и 1,16 секунды для приложения C # (оба в сборке выпуска). Поскольку приложение C # является очень простым и выделяет память, используемую в цикле, в стеке, а не в куче, оно фактически работает намного лучше, чем реальное приложение, задействованное в объектах, сложных вычислениях и с большими наборами данных. Таким образом, приведенные цифры являются оптимистичными, смещенными в сторону C # и платформы .NET. Даже с таким смещением приложение C ++ завершает работу чуть более чем в два раза быстрее, чем эквивалентное приложение C #. Помните, что используемый мной компилятор Microsoft C ++ не имел правильного конвейера и оптимизаций гиперпоточности (используя WinDBG для просмотра инструкций по сборке).
Теперь, если мы используем компилятор Intel (который, кстати, является отраслевым секретом для создания высокопроизводительных приложений на процессорах AMD / Intel), тот же код выполняется за 0,54 секунды для исполняемого файла C ++ по сравнению с 0,72 секунды с использованием Microsoft Visual Studio 2010. Таким образом, в конечном итоге конечные результаты составляют 0,54 секунды для C ++ и 1,16 секунды для C #. Таким образом, код, создаваемый компилятором .NET JIT, занимает в 214% больше времени, чем исполняемый файл C ++. Большая часть времени, проведенного за .54 секунды, была связана с получением времени от системы, а не внутри самого цикла!
В статистике также не хватает времени запуска и очистки, которые не включены в тайминги. Приложения C # тратят намного больше времени на запуск и завершение, чем приложения C ++. Причина этого сложна и связана с процедурами проверки кода во время выполнения .NET и подсистемой управления памятью, которая выполняет большую работу в начале (и, следовательно, в конце) программы для оптимизации распределения памяти и мусора. коллектор.
При измерении производительности C ++ и .NET IL важно взглянуть на код сборки, чтобы убедиться, что ВСЕ расчеты выполнены. Я обнаружил, что без добавления дополнительного кода в C # большая часть кода в приведенных выше примерах фактически была удалена из двоичного кода. Так было и в случае с C ++, когда вы использовали более агрессивный оптимизатор, такой как тот, который поставляется с компилятором Intel C ++. Результаты, которые я предоставил выше, на 100% верны и проверены на уровне сборки.
Основная проблема на многих форумах в Интернете - многие новички слушают маркетинговую пропаганду Microsoft, не понимая технологии, и делают ложные заявления о том, что C # быстрее C ++. Утверждается, что в теории C # быстрее, чем C ++, потому что JIT-компилятор может оптимизировать код для процессора. Проблема этой теории заключается в том, что в среде .NET существует множество трубопроводов, которые снижают производительность; сантехника, которой нет в приложении C ++. Кроме того, опытный разработчик будет знать правильный компилятор для данной платформы и использовать соответствующие флаги при компиляции приложения. На платформах Linux или с открытым исходным кодом это не является проблемой, поскольку вы можете распространять свой исходный код и создавать сценарии установки, которые компилируют код с использованием соответствующей оптимизации. На платформе Windows или с закрытым исходным кодом вам придется распространять несколько исполняемых файлов, каждый с определенной оптимизацией. Развертываемые двоичные файлы Windows основаны на ЦП, обнаруженном установщиком msi (с использованием пользовательских действий).