Я разработчик C ++ и C #. Я разрабатывал приложения на C # с момента выхода первой бета-версии платформы .NET, и у меня более 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 ++. Большая часть времени, потраченного на 0,54 секунды, была связана с получением времени от системы, а не внутри самого цикла!
Чего также не хватает в статистике, так это времени запуска и очистки, которые не включены в тайминги. Приложения C # обычно тратят намного больше времени на запуск и завершение работы, чем приложения C ++. Причина этого сложна и связана с процедурами проверки кода среды выполнения .NET и подсистемой управления памятью, которая выполняет большую работу в начале (и, следовательно, в конце) программы для оптимизации распределения памяти и мусора. коллектор.
При измерении производительности C ++ и .NET IL важно смотреть на ассемблерный код, чтобы убедиться, что ВСЕ вычисления выполняются. Я обнаружил, что без добавления дополнительного кода на C # большая часть кода в приведенных выше примерах была фактически удалена из двоичного файла. То же самое и с C ++, когда вы использовали более агрессивный оптимизатор, такой как тот, который поставляется с компилятором Intel C ++. Результаты, которые я предоставил выше, верны на 100% и проверены на уровне сборки.
Основная проблема в том, что множество форумов в Интернете состоит в том, что многие новички слушают маркетинговую пропаганду Microsoft, не понимая технологии, и делают ложные заявления о том, что C # быстрее, чем C ++. Утверждается, что теоретически C # быстрее, чем C ++, потому что JIT-компилятор может оптимизировать код для ЦП. Проблема с этой теорией состоит в том, что в .NET framework существует множество проблем, снижающих производительность; сантехника, которой нет в приложении C ++. Кроме того, опытный разработчик будет знать, какой компилятор использовать для данной платформы, и будет использовать соответствующие флаги при компиляции приложения. На платформах Linux или с открытым исходным кодом это не проблема, потому что вы можете распространять исходный код и создавать сценарии установки, которые компилируют код с использованием соответствующей оптимизации. На платформе Windows или с закрытым исходным кодом вам придется распространить несколько исполняемых файлов, каждый с определенной оптимизацией. Двоичные файлы Windows, которые будут развернуты, зависят от ЦП, обнаруженного установщиком msi (с использованием настраиваемых действий).