Насколько быстрее С++, чем С#?

Или теперь это наоборот?

Из того, что я слышал, есть некоторые области, в которых С# оказывается быстрее С++, но у меня никогда не было смелости проверить его самостоятельно.

Подумал, что любой из вас мог бы объяснить эти различия подробно или указать мне нужное место для информации об этом.

Ответ 1

Не существует строгой причины, почему язык на основе байт-кода, например С# или Java, который имеет JIT, не может быть таким же быстрым, как код С++. Однако код С++ был значительно быстрее в течение длительного времени, а также сегодня по-прежнему во многих случаях. В основном это связано с тем, что более сложные JIT-оптимизации сложны для реализации, и действительно крутые только сейчас появляются.

Таким образом, С++ быстрее, во многих случаях. Но это только часть ответа. Случаи, когда С++ на самом деле быстрее, являются высоко оптимизированными программами, где экспертные программисты тщательно оптимизировали ад из кода. Это не только очень много времени (и, следовательно, дорого), но также часто приводит к ошибкам из-за чрезмерной оптимизации.

С другой стороны, код в интерпретируемых языках ускоряется в более поздних версиях среды выполнения (.NET CLR или Java VM), без каких-либо действий. И есть много полезных оптимизаций, которые могут сделать компиляторы JIT, которые просто невозможны на языках с указателями. Кроме того, некоторые утверждают, что сбор мусора должен быть таким же быстрым или быстрым, как ручное управление памятью, и во многих случаях это так. Вы можете вообще реализовать и достичь всего этого в С++ или C, но это будет намного сложнее и подвержено ошибкам.

Как сказал Дональд Кнут, "преждевременная оптимизация - это корень всего зла". Если вы действительно знаете наверняка, что ваше приложение будет в основном состоять из критической арифметики с высокой производительностью, и что это будет узким местом, и это, безусловно, будет быстрее на С++, и вы уверены, что С++ не будет конфликтовать с вашим другим требования, перейдите на С++. В любом другом случае сосредоточьтесь на том, чтобы вначале реализовать свое приложение правильно на любом языке, который подходит вам лучше всего, а затем найдите узкие места производительности, если он работает слишком медленно, а затем подумайте о том, как оптимизировать код. В худшем случае вам может потребоваться вызывать код C через внешний интерфейс, так что вы все равно сможете писать критические части на языке более низкого уровня.

Имейте в виду, что относительно легко оптимизировать правильную программу, но гораздо сложнее исправить оптимизированную программу.

Предоставление фактических процентов преимуществ скорости невозможно, это во многом зависит от вашего кода. Во многих случаях реализация языка программирования даже не является узким местом. С высокой степенью скептицизма придерживайтесь критериев http://benchmarksgame.alioth.debian.org/, поскольку они в основном проверяют арифметический код, который, скорее всего, не похож на ваш код на все.

Ответ 2

С# может быть не быстрее, но он ускоряет работу YOU/ME. Это самая важная мера для того, что я делаю.:)

Ответ 3

Это пять апельсинов быстрее. Вернее: не может быть (правильного) полного ответа. С++ - это статически скомпилированный язык (но тогда и оптимизация, управляемая профилем), С# работает с помощью JIT-компилятора. Есть так много различий, на которые нельзя ответить на такие вопросы, как "насколько быстрее", даже не называя порядка.

Ответ 4

Я собираюсь начать с несогласия с частью принятого (и хорошо проголосовавшего) ответа на этот вопрос, заявив:

На самом деле существует множество причин, по которым код JITted будет работать медленнее, чем должным образом оптимизированная C++ (или другой язык без затрат времени выполнения), включая:

  • вычислительные циклы, затрачиваемые на код JITting во время выполнения, по определению недоступны для использования при выполнении программы.

  • любые горячие пути в JITter будут конкурировать с вашим кодом для инструкций и кэширования данных в CPU. Мы знаем, что кэш доминирует, когда дело доходит до производительности, и родные языки, такие как C++, по определению не имеют такого типа конфликта.

  • бюджет времени оптимизатора времени выполнения обязательно намного более ограничен, чем бюджет оптимизатора времени компиляции (как отметил другой комментатор)

Итог: в конечном итоге вы почти наверняка сможете создать более быструю реализацию в C++, чем в С#.

Теперь, с учетом сказанного, насколько быстрее на самом деле не поддается количественной оценке, поскольку существует слишком много переменных: задача, проблемная область, оборудование, качество реализаций и многие другие факторы. Вы проведете тесты по своему сценарию, чтобы определить разницу в производительности, а затем решить, стоит ли это дополнительных усилий и сложности.

Это очень длинная и сложная тема, но я считаю, что ради полноты стоит упомянуть, что оптимизатор времени выполнения С# превосходен и способен выполнять определенные динамические оптимизации во время выполнения, которые просто недоступны для C++ с его компиляцией. временный (статический) оптимизатор. Даже при этом, как правило, преимущество по-прежнему глубоко в нативном суде приложений, но динамический оптимизатор является причиной почти наверняка приведенного выше квалификатора.

-

Что касается относительной эффективности, меня также беспокоили цифры и обсуждения, которые я видел в некоторых других ответах, поэтому я подумал, что я должен присоединиться и в то же время оказать некоторую поддержку заявлениям, которые я сделал выше.

Огромная часть проблемы этих тестов заключается в том, что вы не можете написать C++ код, как если бы вы писали на С#, и ожидаете получить репрезентативные результаты (например, выполнение тысяч выделений памяти в C++ даст вам ужасные цифры.)

Вместо этого я написал немного более идиоматический код C++ и сравнил его с кодом С#, предоставленным @Wiory. Два основных изменения, которые я внес в код C++:

1) используемый вектор :: резерв()

2) сглаживает массив 2d до 1d для достижения лучшей локализации кэша (непрерывный блок)

С# (.NET 4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

Время выполнения (выпуск): инициализация: 124мс, заполнение: 165мс

C++ 14 (Clang v3.8/C2)

#include <iostream>
#include <vector>

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector<double>();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast<std::chrono::microseconds>(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast<double>(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast<std::chrono::milliseconds>(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

Время выполнения (выпуск): Инициализация: 398 мкс (да, это микросекунды), заполнение: 152 мс

Общее время выполнения: С#: 289 мс, C++ 152 мс (примерно на 90% быстрее)

наблюдения

  • Изменение реализации С# на ту же реализацию 1d массива привело к Init: 40 мс, Fill: 171 мс, итого: 211 мс (C++ все еще был почти на 40% быстрее).

  • Намного сложнее спроектировать и написать "быстрый" код в C++, чем написать "обычный" код на любом языке.

  • (Возможно) удивительно легко получить плохую производительность в C++; мы видели это с незарезервированными векторами производительности. И таких ловушек много.

  • Производительность С# довольно удивительна, если учесть все, что происходит во время выполнения. И эта производительность сравнительно легко доступна.

  • Дополнительные анекдотичные данные, сравнивающие производительность C++ и С#: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

Суть в том, что C++ дает вам гораздо больший контроль над производительностью. Вы хотите использовать указатель? Ссылка? Стек памяти? Heap? Динамический полиморфизм или устранение накладных расходов во время выполнения виртуальной таблицы со статическим полиморфизмом (через шаблоны /CRTP)? В C++ вы должны... делать все эти выборы (и даже больше) самостоятельно, в идеале, чтобы ваше решение наилучшим образом решало проблему, которую вы решаете.

Спросите себя, действительно ли вы хотите или нуждаетесь в этом контроле, потому что даже для приведенного выше тривиального примера вы можете видеть, что, несмотря на значительное улучшение производительности, для доступа к нему требуются более глубокие инвестиции.

Ответ 5

По моему опыту (и я много работал с обоими языками), основная проблема с С# по сравнению с С++ - это высокая потребляемая память, и я не нашел хороший способ ее контролировать. Это было потребление памяти, которое в конечном итоге замедлит работу программного обеспечения .NET.

Другим фактором является то, что компилятор JIT не может позволить себе слишком много времени для выполнения расширенных оптимизаций, поскольку он работает во время выполнения, и конечный пользователь заметил бы это, если потребуется слишком много времени. С другой стороны, компилятор С++ всегда должен выполнять оптимизацию во время компиляции. Этот фактор намного менее значителен, чем потребление памяти, IMHO.

Ответ 6

Один конкретный сценарий, когда С++ все еще имеет верх (и будет, на долгие годы), возникает, когда полиморфные решения могут быть заданы во время компиляции.

Как правило, инкапсуляция и отложенное принятие решений - это хорошо, потому что это делает код более динамичным, легче адаптируется к изменяющимся требованиям и проще использовать в качестве основы. Вот почему объектно-ориентированное программирование на С# очень продуктивно и его можно обобщить под термином "обобщение". К сожалению, этот особый вид обобщения приходит во время выполнения.

Обычно эта стоимость несущественна, но есть приложения, где накладные расходы на вызовы виртуальных методов и создание объектов могут иметь значение (особенно, поскольку виртуальные методы предотвращают другие оптимизации, такие как inline). Здесь С++ имеет огромное преимущество, поскольку вы можете использовать шаблоны для достижения другого рода обобщений, которые не влияют на время выполнения, но не обязательно являются менее полиморфными, чем ООП. Фактически, все механизмы, которые составляют ООП, могут быть смоделированы с использованием только методов шаблонов и разрешения времени компиляции.

В таких случаях (и, по общему признанию, они часто ограничиваются специальными предметными областями), С++ выигрывает против С# и сопоставимых языков.

Ответ 7

C++ (или C в этом отношении) дает вам детальный контроль над вашими структурами данных. Если вы хотите немного покататься, у вас есть такая опция. Большие управляемые приложения Java или .NET(OWB, Visual Studio 2005), которые используют внутренние структуры данных библиотек Java/.NET, несут с собой багаж. Я видел сеансы OWB-дизайнеров, использующие более 400 МБ ОЗУ и BIDS для куба или ETL, а также 100 МБ.

При предсказуемой рабочей нагрузке (такой как большинство тестов, которые повторяют процесс много раз) JIT может получить код, который достаточно хорошо оптимизирован, чтобы не было практической разницы.

IMO для больших приложений, разница не столько в JIT, сколько в структурах данных, которые использует сам код. Если приложение занимает много памяти, вы получите менее эффективное использование кэша. Промах кэша на современных процессорах довольно дорогой. Где C или C++ действительно выигрывают, это где вы можете оптимизировать использование структур данных, чтобы хорошо играть с кешем процессора.

Ответ 8

Для графики стандартный класс С# Graphics намного медленнее, чем GDI, доступ к которому осуществляется через C/С++. Я знаю, что это не имеет никакого отношения к языку как таковому, больше с общей платформой .NET, но Graphics - это то, что предлагается разработчику как замена GDI, и его производительность настолько плохая, что я даже не рискнул бы делать графику с ним.

У нас есть простой тест, который мы используем, чтобы увидеть, насколько быстро графическая библиотека, и это просто рисование случайных строк в окне. С++/GDI по-прежнему остается 10000 строк, в то время как С#/Graphics испытывает трудности с выполнением 1000 в режиме реального времени.

Ответ 9

Сбор мусора является основной причиной того, что Java # НЕ МОЖЕТ использоваться для систем реального времени.

  • Когда произойдет GC?

  • Как долго это займет?

Это не детерминировано.

Ответ 10

Нам нужно было определить, был ли С# сопоставим с С++ в производительности, и я написал для него несколько тестовых программ (используя Visual Studio 2005 для обоих языков). Оказалось, что без сбора мусора и только с учетом языка (а не рамки) С# имеет в основном ту же производительность, что и С++. Распределение памяти происходит быстрее на С#, чем на С++, а С# имеет небольшое преимущество в детерминизме, когда размеры данных увеличиваются за пределами границ строки кэша. Тем не менее, все это в конечном итоге должно быть оплачено, и есть огромная стоимость в виде недетерминированных результатов производительности для С# из-за сбора мусора.

Ответ 11

Как обычно, это зависит от приложения. Бывают случаи, когда С#, вероятно, небрежно медленнее, и в других случаях, когда С++ в 5 или 10 раз быстрее, особенно в тех случаях, когда операции могут быть легко SIMD'd.

Ответ 12

Я знаю, что это не то, что вы просили, но С# часто быстрее писать, чем С++, что является большим бонусом в коммерческих настройках.

Ответ 13

> Из того, что я слышал...

Ваша трудность, по-видимому, заключается в том, чтобы решить, насколько достоверно слышно то, что вы слышали, и эта трудность будет просто повторяться, когда вы попытаетесь оценить ответы на этом сайте.

Как вы собираетесь решить, являются ли те вещи, которые люди говорят здесь, более или менее достоверны, чем то, что вы изначально слышали?

Один из способов - попросить доказательства.

Когда кто-то утверждает: "Есть некоторые области, в которых С# оказывается быстрее С++" спросите их, почему они говорят, что, попросите их показать свои измерения, попросите их показать вам программы. Иногда они просто совершают ошибку. Иногда вы обнаружите, что они просто выражают мнение, а не разделяют то, что они могут показать, чтобы быть правдой.

Часто информация и мнение будут замешаны в том, что люди требуют, и вам придется попробовать и разобраться, что есть. Например, из ответов на этом форуме:

  • "Выполните тесты в http://shootout.alioth.debian.org/ с большим скептицизмом, поскольку это в основном тестовый арифметический код, который, скорее всего, не похож на ваш код вообще. "

    Спросите себя, действительно ли вы понять, что "в основном они испытывают арифметический код ", а затем спросите себя, есть ли у автора фактически показал вам, что его требование правда.

  • "Это довольно бесполезный тест, поскольку он действительно зависит от того, насколько хорошо отдельные программы были оптимизировано; Мне удалось ускорить некоторые из них в 4-6 раз и более, давая понять, что сравнение между неоптимизированными программами довольно глупый ".

    Спросите себя, есть ли у автора фактически показал вам, что он справился "ускорить некоторые из них на 4-6 раз или больше "- это легкое выражение о том, чтобы сделать!

Ответ 14

C/С++ может значительно улучшиться в программах, где есть большие массивы или тяжелая петля/итерация по массивам (любого размера). Это связано с тем, что графика, как правило, намного быстрее в C/С++, поскольку операции с тяжелым массивом лежат в основе почти всех графических операций..NET заведомо медлил в операциях индексирования массивов из-за всех проверок безопасности, и это особенно верно для многомерных массивов (и, да, прямоугольные массивы С# еще медленнее, чем зубчатые массивы С#).

Бонусы C/С++ наиболее выражены, если вы прямо придерживаетесь указателей и избегаете Boost, std::vector и других контейнеров высокого уровня, а также inline каждую возможную небольшую функцию. По возможности используйте макеты старой школы. Да, вам понадобится больше строк кода для выполнения того же самого действия, что и на Java или С#, поскольку вы избегаете контейнеров высокого уровня. Если вам нужен массив с динамическим размером, вам просто нужно запомнить пару new T[] с соответствующим оператором delete[] (или использовать std::unique_ptr) — цена на дополнительную скорость - это то, что вы должны более тщательно прописать код. Но взамен вы избавляетесь от накладных расходов управляемой памяти/сборщика мусора, что может быть легко на 20% и более от времени выполнения сильно объектно-ориентированных программ как на Java, так и на .NET, а также на тех крупных управляемых расходы на индексацию памяти. Приложения С++ также могут извлечь выгоду из некоторых отличных переключателей компилятора в определенных конкретных случаях.

Я эксперт-программист на C, С++, Java и С#. Недавно у меня был редкий случай реализовать ту же самую алгоритмическую программу на последних трех языках. В программе было много математических и многомерных операций с массивами. Я сильно оптимизировал это на всех трех языках. Результаты были типичными для того, что я обычно вижу в менее строгих сравнениях: Java примерно на 1,3 раза быстрее, чем С# (большинство JVM более оптимизированы, чем CLR), а версия исходного кода С++ - примерно в 2,1 раза быстрее, чем С#. Обратите внимание, что в программе на С# используется только безопасный код. По моему мнению, вы можете также скопировать его на С++ перед использованием ключевого слова unsafe.

Чтобы кто-нибудь не подумал, что у меня что-то есть против С#, я закрою, сказав, что С#, вероятно, мой любимый язык. Это самый логичный, интуитивно понятный и быстрый язык разработки, с которым я столкнулся до сих пор. Я делаю все свое прототипирование на С#. Язык С# имеет множество небольших, тонких преимуществ по сравнению с Java (да, я знаю, что у Microsoft была возможность исправить многие недостатки Java, войдя в игру поздно и, возможно, копируя Java). Тост на Java Calendar класс? Если Microsoft когда-либо тратит реальные усилия на оптимизацию CLR и .NET JITter, С# может серьезно заняться. Я искренне удивлен, что они еще не сделали этого: они сделали так много всего на языке С#, почему бы не следить за ним с помощью оптимизаторов компилятора с сильным ударом? Может быть, если мы все попросим.

Ответ 15

Языки .NET могут быть такими же быстрыми, как С++-код, или даже быстрее, , но код С++ будет иметь более постоянную пропускную способность, так как среда выполнения .NET должна приостанавливаться для GC, даже если он очень умен в своих паузах.

Итак, если у вас есть код, который должен быстро запускаться без паузы,.NET будет вводить латентность в какой-то момент, даже если вы очень осторожны с GC среды выполнения.

Ответ 16

Это очень неопределенный вопрос без реальных окончательных ответов.

Например; Я предпочел бы играть в 3D-игры, созданные на С++, чем на С#, потому что производительность, безусловно, намного лучше. (И я знаю XNA и т.д., Но это не похоже на реальную вещь).

С другой стороны, как упоминалось ранее; вы должны развиваться на языке, который позволяет быстро делать то, что вам нужно, а затем при необходимости оптимизировать.

Ответ 17

Для проблем с "неудобной параллельностью" при использовании Intel TBB и OpenMP на С++ я наблюдал примерно 10-кратное увеличение производительности по сравнению с аналогичными (чистыми математическими) проблемами, выполняемыми с С# и TPL. SIMD - это одна из областей, где С# не может конкурировать, но у меня также сложилось впечатление, что TPL имеет значительные накладные расходы.

Тем не менее, я использую только С++ для критически важных задач, где я знаю, что смогу многопоточно и быстро получить результаты. Для всего остального С# (а иногда и F #) просто отлично.

Ответ 18

В теории, для долгого приложения серверного типа, скомпилированный язык JIT может стать намного быстрее, чем исходно скомпилированный аналог. Поскольку скомпилированный язык JIT обычно сначала компилируется на довольно низкий уровень промежуточного языка, вы можете сделать много оптимизаций высокого уровня прямо во время компиляции. Большим преимуществом является то, что JIT может продолжать перекомпилировать разделы кода "на лету", поскольку он получает все больше и больше данных о том, как приложение используется. Он может организовать наиболее распространенные кодовые пути, чтобы позволить предсказанию ветвей добиться успеха как можно чаще. Он может переустанавливать отдельные блоки кода, которые часто вызываются вместе, чтобы сохранить их в кеше. Он может потратить больше усилий на оптимизацию внутренних циклов.

Я сомневаюсь, что это сделано .NET или какой-либо из JRE, но его изучали, когда я был в университете, поэтому неразумно думать, что подобные вещи могут найти свой путь в реальном мире на немного скоро.

Ответ 19

Приложения, требующие интенсивного доступа к памяти, например. манипуляции с изображениями обычно лучше записываются в неуправляемой среде (С++), чем управляемый (С#). Оптимизированные внутренние петли с арифметикой указателей намного легче контролировать на С++. В С# вам может потребоваться использовать небезопасный код, чтобы он даже приблизился к той же производительности.

Ответ 20

Я тестировал vector в С++ и С# эквиваленте - List и простые 2d массивы.

Я использую Visual С#/С++ 2010 Express. Оба проекта - это простые консольные приложения, я тестировал их в стандартном (без специальных настроек) режиме выпуска и отладки. Списки С# запускаются быстрее на моем компьютере, инициализация массива также быстрее в С#, математические операции медленнее.

Я использую Intel Core2Duo [email protected], С# -.NET 4.0.

Я знаю, что векторная реализация отличается от списка С#, но я просто хотел проверить коллекции, которые я буду использовать для хранения моих объектов (и возможность использовать индексный аксессуар).

Конечно, вам нужно очистить память (допустим, для каждого использования new), но я хотел, чтобы код был прост.

векторный тест С++:

static void TestVector()
{
    clock_t start,finish;
    start=clock();
    vector<vector<double>> myList=vector<vector<double>>();
    int i=0;
    for( i=0; i<500; i++)
    {
        myList.push_back(vector<double>());
        for(int j=0;j<50000;j++)
            myList[i].push_back(j+i);
    }
    finish=clock();
    cout<<(finish-start)<<endl;
    cout<<(double(finish - start)/CLOCKS_PER_SEC);
}

Тест списка С#:

private static void TestVector()
{

    DateTime t1 = System.DateTime.Now;
    List<List<double>> myList = new List<List<double>>();
    int i = 0;
    for (i = 0; i < 500; i++)
    {
        myList.Add(new List<double>());
        for (int j = 0; j < 50000; j++)
            myList[i].Add(j *i);
    }
    DateTime t2 = System.DateTime.Now;
    Console.WriteLine(t2 - t1);
}

С++ - массив:

static void TestArray()
{
    cout << "Normal array test:" << endl;
    const int rows = 5000;
    const int columns = 9000;
    clock_t start, finish;

    start = clock();
    double** arr = new double*[rows];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    finish = clock();

    cout << (finish - start) << endl;

    start = clock();
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    finish = clock();

    cout << (finish - start) << endl;
}

С# - массив:

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i * j;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

}

Время: (Отпуск/Отладка)

С++

  • 600/606 ms array init,
  • заполнение массива 200/270 мс,
  • 1 сек. /13 сек. vector init и fill.

(Да, 13 секунд, у меня всегда проблемы со списками/векторами в режиме отладки.)

С#

  • 20/20 мс array init,
  • 403/440 мс заполнить,
  • 710/742 мс введите init и заполните.

Ответ 21

Ну, это зависит. Если байт-код переведен в машинный код (а не только JIT) (я имею в виду, если вы выполняете программу), и если ваша программа использует много распределений/освобождений, это может быть быстрее, потому что GC алгоритму требуется всего один проход (теоретически) через всю память один раз, но нормальные вызовы malloc/realloc/free C/С++ приводят к накладным расходам на каждый вызов (служебные данные, служебные данные структуры, пропуски кэша;)).

Таким образом, теоретически это возможно (также для других языков GC).

Я действительно не вижу крайнего недостатка в том, чтобы не использовать metaprogramming с С# для большинства приложений, потому что большинство программистов не используют его в любом случае.

Еще одно большое преимущество заключается в том, что SQL, например, LINQ, предоставляет возможности для компилятора оптимизировать вызовы в базы данных (в другими словами, компилятор может скомпилировать весь LINQ в один двоичный код "blob", где вызываемые функции встроены или для вашего использования оптимизированы, но я размышляю здесь).

Ответ 22

Я полагаю, что приложения, написанные на С#, работают быстро, а также написание написанных приложений на С++ быстро (ну, С++ просто старше... и тоже UNIX...)
- вопрос действительно есть - что это такое, пользователи и разработчики жалуются на... Ну, ИМХО, в случае С# у нас очень удобный интерфейс, очень хорошая иерархия библиотек и целая система интерфейса CLI. В случае С++ у нас есть шаблоны, ATL, COM, MFC и целые shebang написанного и исполняемого кода alreadyc, такие как OpenGL, DirectX и т.д. Разработчики жалуются на неопределенно увеличивающиеся вызовы GC в случае С# (означает, что программа выполняется быстро и через одну секунду - удар! он застрял).
Написать код на С# очень просто и быстро (не забывать, что также увеличивает вероятность ошибок. В случае С++ разработчики жалуются на утечки памяти, - означает раздачи, вызовы между DLL, а также "DLL hell" - проблема с поддержкой и заменой библиотек более новыми...
Я думаю, что больше навыков у вас будет на языке программирования, тем больше качество (и скорость) будет характеризовать ваше программное обеспечение.

Ответ 23

Я бы сказал так: программисты, которые пишут более быстрый код, являются теми, кто более информирован о том, что делает текущие машины быстрыми, и, кстати, они также используют подходящий инструмент, уровня и методов детерминированной оптимизации. По этим причинам эти люди используют C/С++, а не С#. Я бы сказал, что это факт.

Ответ 24

> В конце концов, ответы должны быть где-то, не так ли?:)

Умм, нет.

Как было отмечено в нескольких ответах, вопрос недоопределен способами, которые приглашают вопросы в ответ, а не ответы. Сделать один способ:

А потом какие программы? Какая машина? Какая ОС? Какой набор данных?

Ответ 25

Если я не ошибаюсь, шаблоны С# определяются во время выполнения. Это должно быть медленнее, чем шаблоны времени компиляции С++.

И когда вы берете на себя все другие оптимизации времени компиляции, упомянутые многими другими, а также отсутствие безопасности, что действительно означает большую скорость...

Я бы сказал, что С++ - это очевидный выбор с точки зрения скорости и минимального потребления памяти. Но это также приводит к увеличению времени разработки кода и обеспечению того, чтобы вы не пропускали память или не вызывали никаких исключений с нулевым указателем.

Вердикт:

  • С#: более быстрое развитие, более медленный запуск

  • С++: медленная разработка, более быстрый запуск.

Ответ 26

Это действительно зависит от того, чего вы пытаетесь достичь в своем коде. Я слышал, что это просто городская легенда, что есть разница в производительности между VB.NET, С# и управляемого C++. Тем не менее, я обнаружил, по крайней мере, в сравнении строк, что C++ ударил штаны из С#, что, в свою очередь, отбросило штаны из VB.NET.

Я ни в коем случае не делал исчерпывающих сравнений алгоритмической сложности между языками. Я также просто использую настройки по умолчанию на каждом из языков. В VB.NET я использую настройки, требующие объявления переменных и т.д. Вот код, который я использую для управляемого C++: (Как видите, этот код довольно прост). Я использую то же самое на других языках в Visual Studio 2013 с .NET 4.6.2.

#include "stdafx.h"

using namespace System;
using namespace System::Diagnostics;

bool EqualMe(String^ first, String^ second)
{
    return first->Equals(second);
}
int main(array<String ^> ^args)
{
    Stopwatch^ sw = gcnew Stopwatch();
    sw->Start();
    for (int i = 0; i < 100000; i++)
    {
        EqualMe(L"one", L"two");
    }
    sw->Stop();
    Console::WriteLine(sw->ElapsedTicks);
    return 0;
}

Ответ 27

Есть некоторые существенные различия между С# и C++ в аспекте производительности:

  • С# основан на GC/куче. Выделение и сам GC являются накладными расходами как нелокальный доступ к памяти
  • C++ оптимизаторы стали очень хорошими за эти годы. JIT-компиляторы не могут достичь того же уровня, так как они имеют только ограниченное время компиляции и не видят глобальную область видимости

Кроме того, компетентность программиста играет также роль. Я видел плохой код C++, где классы передавались по значению в качестве аргумента повсюду. В C++ вы можете сделать еще хуже, если не будете обращать на это внимания.

Ответ 28

Вдохновленный этим, я сделал быстрый тест с 60 процентами общей инструкции, необходимой в большинстве программ.

Вот код С#:

for (int i=0; i<1000; i++)
{
    StreamReader str = new StreamReader("file.csv");
    StreamWriter stw = new StreamWriter("examp.csv");
    string strL = "";
    while((strL = str.ReadLine()) != null)
    {
        ArrayList al = new ArrayList();
        string[] strline = strL.Split(',');
        al.AddRange(strline);
        foreach(string str1 in strline)
        {
            stw.Write(str1 + ",");
        }
        stw.Write("\n");
    }
    str.Close();
    stw.Close();
}

Строковый массив и arraylist используются специально для включения этих инструкций.

Здесь код С++:

for (int i = 0; i<1000; i++)
{
    std::fstream file("file.csv", ios::in);
    if (!file.is_open())
    {
        std::cout << "File not found!\n";
        return 1;
    }

    ofstream myfile;
    myfile.open ("example.txt");
    std::string csvLine;

    while (std::getline(file, csvLine))
    {
        std::istringstream csvStream(csvLine);
        std::vector csvColumn;
        std::string csvElement;

        while( std::getline(csvStream, csvElement, ‘,’) )
        {
            csvColumn.push_back(csvElement);
        }

        for (std::vector::iterator j = csvColumn.begin(); j != csvColumn.end(); ++j)
        {
            myfile << *j << ", ";
        }

        csvColumn.clear();
        csvElement.clear();
        csvLine.clear();
        myfile << "\n";
    }
    myfile.close();
    file.close();
}

Размер входного файла, который я использовал, был 40 KB.

И вот результат -

  • Код С++ запускался через 9 секунд.
  • Код С#: 4 секунды!!!

О, но это было в Linux... С С#, работающим на Mono... И С++ с g++.

ОК, это то, что я получил в Windows - Visual Studio 2003:

  • Код С# за 9 секунд.
  • Код С++ - ужасный 370 секунд!!!