Подтвердить что ты не робот

Что быстрее - Java или С# (или старый добрый C)?

В настоящее время я решаю на платформу для создания научного вычислительного продукта, и я решаю на С#, Java или просто C с компилятором Intel на процессорах Core2 Quad. Это в основном целочисленная арифметика.

Мои тесты пока показывают, что Java и C находятся на одном уровне друг с другом, а трассы .NET/С# - примерно на 5%, однако некоторые мои коллеги утверждают, что .NET с правильной оптимизацией будет бить оба этих при условии, что JIT выполнит свою работу.

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

Может ли кто-нибудь пролить свет на ситуацию? Будет ли .NET бить Java? (Или мне лучше всего придерживаться C в этот момент?).

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

Haskell/Erlang и т.д. не являются параметрами в этом случае, так как существует значительное количество существующего унаследованного кода C, который будет перенесен в новую систему, а перенос C на Java/С# намного проще, чем на Haskell или Erlang. (Если, конечно, это не дает значительного ускорения).

Edit: Мы рассматриваем переход на С# или Java, потому что они могут, теоретически, быть быстрее. Каждый процент, который мы можем свести с нашего времени обработки, сэкономит нам десятки тысяч долларов в год. На этом этапе мы просто пытаемся оценить, будет ли C, Java или С# быстрее.

4b9b3361

Ответ 1

Ключевой информацией в вопросе является следующее:

Каждый процент, который мы можем сбрить время обработки экономит нам десятки тысячи долларов в год

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

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

Я бы предположил, что если у вас есть код, уже написанный на C, попытка переписать все это как прямой перевод на другом языке будет 90% потрачено впустую. Это, скорее всего, будет выполняться медленнее просто потому, что вы не будете использовать возможности платформы, но вместо этого будете работать против них, например. пытаясь использовать Java, как будто это был C.

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

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

Обновить, когда я заметил ссылку на код "многопоточность"

В этом случае, если вы сосредоточите свое внимание на устранении узких мест, чтобы ваша программа могла масштабироваться по большому количеству ядер, она автоматически будет быстрее работать с каждым годом со скоростью, которая будет затмевать любую другую оптимизацию, которую вы можете сделать. На этот раз в следующем году четырехъядерные ядра будут стандартными для настольных компьютеров. Через год 8 ядер будут дешевле (я купил один год назад на несколько тысяч долларов), и я бы предсказал, что 32-ядерная машина будет стоить меньше, чем разработчик к тому времени.

Ответ 2

Извините, но это не простой вопрос. Это будет зависеть от того, что именно происходит. С#, безусловно, не сутулиться, и вам будет трудно сказать, что "java быстрее" или "С# быстрее". C - совсем другой зверь... возможно, он может быть быстрее - , если, вы понимаете это правильно; но в большинстве случаев это будет примерно то же самое, но гораздо сложнее написать.

Это также зависит от того, как вы это делаете - стратегии блокировки, как вы выполняете распараллеливание, тело основного кода и т.д.

Re JIT - вы можете использовать NGEN, чтобы сгладить это, но да; если вы нажимаете один и тот же код, он должен быть JITted очень рано.

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

Также - с .NET, рассмотрите такие вещи, как "Параллельные расширения" (в комплекте в 4.0), что дает вам гораздо более сильную историю потоков (по сравнению с .NET без PFX).

Ответ 3

Не беспокойтесь о языке; распараллеливать!

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

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

Я думаю, вы должны рассмотреть два варианта:

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

    Hadoop масштабируется до 10 000 узлов в Linux, и вы можете отключить свою работу от кого-то другого (например, Amazon's, Microsoft) или собственного облака вычислений. Он написан на Java, так как портирование идет, вы можете либо вызывать свой существующий код C из Java, либо переносить все на Java.

  • MPI
    Если вы не хотите беспокоиться о переносе в MapReduce или если по какой-то причине ваша параллельная парадигма не подходит для модели MapReduce, вы можете рассмотреть возможность адаптации вашего приложения для использования MPI. Это также позволит вам масштабировать (потенциально тысячи) ядер. MPI является де-факто стандартом для вычислительно интенсивных приложений с распределенной памятью, и я считаю, что есть привязки Java, но в основном люди используют MPI с C, С++ и Fortran. Таким образом, вы можете сохранить свой код на C и сосредоточиться на распараллеливании деталей, требующих высокой производительности. Посмотрите OpenMPI для начала, если вы заинтересованы.

Ответ 4

Я честно удивлен этими критериями.

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

Единственная причина, по которой я мог бы думать, что Java или С# будет быстрее, - это короткая продолжительность теста. Если мало или вообще не произошло GC, вы избежите накладных расходов на фактическое освобождение памяти. Если процесс является итеративным или параллельным, попробуйте использовать GC.Collect, где бы вы ни думали, что вы сделали кучу объектов (после того, как объекты были нулевыми или иначе удалены ссылки).

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

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

Ответ 5

Довольно давно Раймонд Чен и Рико Мариани имел ряд сообщений в блогах, которые постепенно оптимизировали загрузку файла в инструмент словаря. В то время как .NET был быстрее на раннем этапе (т.е. Легко сделать быстрый), подход C/Win32 в конечном итоге был значительно быстрее - но со значительной сложностью (например, с использованием пользовательских распределителей).

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


Первая и последняя записи в блоге:

(Последняя ссылка дает общее резюме результатов и некоторый анализ.)

Ответ 6

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

Итак, это зависит от того, что вы делаете, я уверен, что вы можете найти что-то, что быстрее в языке X, чем язык Y.

Вы пытались запустить код С# через профилировщик, чтобы увидеть, где он занимает больше всего времени (то же самое с Java и C, пока вы на нем). Возможно, вам нужно сделать что-то другое.

Java HotSpot VM более зрелая (ее корни вернутся, по крайней мере, до 1994 года), чем .NET, поэтому она может перейти к возможностям генерации кода для обоих.

Ответ 7

Вы говорите: "код многопоточен", что означает, что алгоритмы параллельны. Кроме того, вы сохраняете "наборы данных размером несколько терабайт".

Оптимизация - это поиск и устранение узких мест.

Очевидным узким местом является пропускная способность для наборов данных. Учитывая размер данных, я предполагаю, что данные хранятся на сервере, а не на настольной машине. Вы не указали какие-либо сведения об используемых вами алгоритмах. Является ли время, затраченное алгоритмом больше времени, затраченного на чтение/запись данных/результатов? Работает ли алгоритм на подмножествах полных данных?

Я собираюсь предположить, что алгоритм работает на кусках данных, а не на весь набор данных.

У вас есть два сценария:

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

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

В первом случае вам нужен разработчик, который может написать хороший код ассемблера, чтобы максимально использовать возможности процессоров, используя SIMD, графические процессоры и многоядерные процессоры, если они доступны. Независимо от того, что вы делаете, не просто сверните количество потоков, потому что, как только количество потоков превысит количество ядер, ваш код будет медленнее! Это связано с добавлением дополнительных ресурсов для переключения контекстов потоков. Другим вариантом является использование SETI, такой как распределенная система обработки (сколько ПК в вашей организации используется для целей администрирования), подумайте обо всей этой свободной вычислительной мощности!). С#/Java, как упоминалось в bh213, может быть на порядок медленнее, чем хорошо написанный C/С++ с использованием SIMD и т.д. Но в наши дни это набор навыков ниши.

В последнем случае, когда вы ограничены полосой пропускания, вам необходимо улучшить сеть, соединяющую данные с процессором. Здесь убедитесь, что вы используете новейшее оборудование Ethernet - всего 1 Гбит/с (карты для ПК, коммутаторы, маршрутизаторы и т.д.). Не используйте беспроводную связь так медленно. Если есть много другого трафика, рассмотрите выделенную сеть параллельно с "офисной" сетью. Рассмотрите возможность хранения данных ближе к клиентам - каждые пять или около того клиенты используют выделенный сервер, подключенный непосредственно к каждому клиенту, который отражает данные с сервера.

Если сохранение нескольких процентов времени обработки экономит "десятки тысяч долларов", тогда серьезно подумайте о том, чтобы получить консультанта, а на самом деле - одно программное обеспечение, одну сеть. Они должны легко расплачиваться за сбережения. Я уверен, что многие здесь могут быть квалифицированы, чтобы помочь.

Но если снижение стоимости является конечной целью, тогда рассмотрите подход Google - напишите код, который удерживает CPU ниже 100%. Это позволяет экономить энергию прямо и косвенно за счет уменьшения охлаждения, поэтому стоимость меньше. Вам понадобится больше ударов для вашего доллара, так что снова C/С++ - у Java/С# больше накладных расходов, накладных расходов - больше работы ЦП = больше энергии/тепла = больше затрат.

Итак, в целом, когда дело доходит до экономии денег, там гораздо больше, чем на каком языке вы собираетесь выбирать.

Ответ 8

Если уже существует значительное количество унаследованного кода C, который будет добавлен в систему, то зачем переходить на С# и Java?

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

Ответ 9

Я участвовал в нескольких матчах TopCoder Marathon, где выступление было ключом к победе.

Мой выбор был С#. Я думаю, что решения С# размещены чуть выше Java и были медленнее, чем С++... Пока кто-то не написал код на С++, который был на порядок быстрее. Вам было предложено использовать компилятор Intel, а выигрышный код был заполнен SIMD-запросами, и вы не можете реплицировать его на С# или Java. Но если SIMD не является вариантом, С# и Java должны быть достаточно хорошими, если вы правильно поработаете с памятью (например, смотрите промахи в кэше и попытайтесь ограничить доступ к памяти к кешу L2)

Ответ 10

На самом деле это "язык ассемблера".

Ответ 12

Чтобы повторить комментарий, вы должны использовать GPU, а не CPU, если вы занимаетесь арифметическими научными вычислениями. Matlab с плагинами CUDA будет намного более привлекательным, чем Java или С#, если лицензирование Matlab не является проблемой. Документация nVidia показывает, как скомпилировать любую функцию CUDA в файл mex. Если вам нужно бесплатное программное обеспечение, мне нравится pycuda. ​​

Если, однако, графические процессоры не являются опцией, мне лично нравится C для многих процедур, потому что оптимизация, которую делает компилятор, не так сложна, как JIT: вам не нужно беспокоиться о том, станет ли "класс" похожим на "struct" или нет. По моему опыту, проблемы обычно могут быть разбиты так, что вещи более высокого уровня могут быть написаны на очень выразительном языке, таком как Python (богатые примитивы, динамические типы, невероятно гибкая рефлексия), а преобразования могут быть написаны на чем-то вроде C. Кроме того, там аккуратное программное обеспечение компилятора, такое как PLUTO (автоматическая параллелизация цикла и генерация кода OpenMP), а также библиотеки, такие как Hoard, tcmalloc, BLAS (CUBLAS для gpu) и т.д., если вы решите пойти по маршруту C/С++.

Ответ 13

Следует отметить, что если ваше приложение выиграет от ленивая оценка функциональный язык программирования например Haskell может давать ускорения совершенно другой величины, чем оптимально структурированный/OO-код, просто не оценивая ненужные ветки.

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

Ответ 14

Вы задаетесь вопросом плохо сформулированным (или, по крайней мере, заголовком), потому что это подразумевает, что эта разница является эндемичной и справедлива для всех экземпляров кода java/С#/c.

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

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

  • Вы не так хороши в написании исполняемого кода С#, как в java/c (это не критика или даже вероятность, но это реальная возможность, которую вы должны рассмотреть)
  • В более поздних версиях JVM есть некоторая серьезная оптимизация, чтобы сделать незащищенные блокировки очень быстрыми. Это может привести к искажениям в вашей пользе (и особенно сравнению с примитивами реализации реализации реализации c, которые вы используете)
  • Так как java-код работает хорошо по сравнению с кодом c, вполне вероятно, что вы не сильно зависите от стратегии распределения кучи (профилирование скажет вам об этом).
  • Так как код С# работает менее эффективно, чем java (и, если предположить, что код сопоставим), существует несколько возможных причин:
    • Вы используете (без необходимости) виртуальные функции, которые JVM будет встроена, но CLR не будет
    • Последняя JVM делает Escape Analysis, который может сделать некоторые кодовые пути значительно более эффективными (особенно те, которые связаны с манипуляцией строк, чье время жизни связано с стеком
    • Только самые последние 32-битные CLR будут встроенными методами, включающими не примитивные структуры
    • Некоторые JVM JIT-компиляторы используют механизмы стиля hotspot, которые пытаются обнаружить "горячие точки" кода и тратят больше усилий на повторное использование их.

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

Ответ 15

Разумеется, ответ заключается в том, чтобы пойти и купить новейший ПК с большинством ядер/процессоров, которые вы можете себе позволить. Если вы купите один из последних 2x4 основных ПК, вы обнаружите, что он не только дважды так как многие ядра являются четырехъядерными ядрами, но также они работают на 25-40% быстрее, чем предыдущие поколения процессоров/машин.

Это даст вам примерно 150% скорости. Гораздо больше, чем выбор Java/С# или C. и чем больше вы получаете то же самое каждые 18 месяцев, если вы продолжаете покупать в новых ящиках!

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

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

Ответ 16

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

  • Покупка новейшего самого быстрого оборудования.
  • Перемещение с 32-разрядной операционной системы на 64 бит.
  • Грид-вычисления.
  • CUDA/OpenCL.
  • Использование оптимизации компилятора, например, векторизация.

Ответ 17

Я бы пошел с С# (или Java), потому что время разработки, вероятно, будет намного быстрее, чем с C. Если вам в итоге нужна дополнительная скорость, вы всегда можете переписать раздел в C и называть его модулем.

Ответ 18

Мое предпочтение было бы C или С++, потому что я не отделен от машинного языка компилятором JIT.

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

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

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

Удачи.

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

Ответ 19

Зависит от того, что вы тестируете и на каком оборудовании. Я предполагаю, что это скорее скорость, чем использование памяти или процессора. Но....

Если у вас есть выделенный компьютер для приложения с очень большим объемом памяти, тогда java может быть на 5% быстрее.

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

Если аппаратное обеспечение очень ограничено, C/С++ выигрывает руки.

Ответ 20

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

Ответ 21

Если ваш код находится в C, почему бы не сохранить его? В принципе и по дизайну очевидно, что C быстрее. Они могут закрыть промежуток с течением времени, но они всегда имеют более высокий уровень os и "безопасность". C быстро, потому что он "небезопасен". Подумайте о связанной проверке. Взаимодействие с C поддерживается в каждом langauge. И поэтому я не понимаю, почему не хотелось бы просто обернуть код C, если он все еще работает, и использовать его на любом языке, который вам нравится.

Ответ 22

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

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

Кроме того, я обнаружил, что приложения С# имеют несколько меньшую, чем оптимальная производительность, в некоторых областях, многопоточность - одна..NET попытается уберечь вас от проблем с потоками (вероятно, это будет хорошо в большинстве случаев), но это вызовет ваши конкретные проблемы с конкретными случаями (для проверки: попробуйте написать простой цикл, который обращается к общему объекту с использованием большого количества потоков. на одном ядре ПК, и вы получаете лучшую производительность, чем если бы вы запускали его в многоядерном ящике -.net добавляет свои собственные блокировки, чтобы убедиться, что вы их не испортили) (я использовал Jon Skeet singleton. Статический замок занял 1.5 секунды на моем старом ноутбуке, 8.5s на моем сверхбыстром рабочем столе, версия блокировки еще хуже, попробуйте сами)

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

Таким образом, может показаться, что С#/Java может дать вам преимущества по сравнению с родным приложением, но я думаю, вы обнаружите, что эти преимущества реализованы только для типов бизнес-приложений, которые обычно пишутся.

Ответ 23

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

Даже для кэша второго уровня большая программа, такая как Quake IV, получает 10% -ное увеличение производительности с кешем уровня 2 МБ против 1 МБ уровня 2 - http://www.tomshardware.com/reviews/cache-size-matter,1709-5.html

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

Ответ 24

Если каждый процент действительно сэкономит вам десятки тысяч долларов, то вам следует привлечь эксперта по домену, чтобы помочь с проектом. Хорошо продуманный и написанный код с производительностью, рассмотренной на начальных этапах, может быть на порядок быстрее, экономя вас на 90%, или на 900 000 долларов. Недавно я обнаружил тонкий недостаток в некотором коде, который ускорил процесс более чем в 100 раз. Один мой коллега нашел алгоритм, который работал в O (n ^ 3), который он переписал, чтобы сделать его O (N log n). Это, как правило, огромная экономия производительности.

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

Ответ 25

Самые важные вещи уже сказано здесь. Я бы добавил:

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

Итак, для "лучшего" выбора языка:

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

Если вы не являетесь экспертом по производительности, вам будет сложно архивировать "максимальную производительность" на любом языке. Возможно, С++ по-прежнему предоставляет большинство параметров для управления машинными инструкциями (особенно SSE-расширениями a.s.o).

Я предлагаю ориентироваться на хорошо известное правило 80:20. Это справедливо для всех: аппаратное обеспечение, языки/платформы и усилия разработчиков.

Разработчики всегда полагались на аппаратное обеспечение, чтобы автоматически исправить все проблемы производительности из-за перехода на более быстрый процессор f.e.. То, что могло бы работать в прошлом, не будет работать в ближайшем будущем. Теперь разработчик обязан структурировать свои программы для параллельного выполнения. Языки для виртуальных машин и виртуальных сред исполнения покажут некоторые преимущества здесь. И даже без массивного распараллеливания мало причин, почему С# или Java не должно быть аналогичным, как С++.

@Edit: см. сравнение С#, Matlab и FORTRAN, где FORTRAN не выигрывает в одиночку!

Ответ 26

Ссылка; "В моих тестах показывается, что Java и C находятся на одном уровне друг с другом"

Тогда ваши тесты сильно испорчены...

C будет ВСЕГДА быть порядками величин быстрее, чем С# и Java, если вы не сделаете что-то серьезно неправильное...!

PS! Обратите внимание, что это не попытка попытаться запугать ни С#, ни Java, мне нравятся как Java, так и С#, и есть другие причины, по которым многие проблемы выбирают Java или С# вместо C. Но ни Java, ни С# в правильные письменные тесты НИКОГДА не могут выполнять с той же скоростью, что и C...

Отредактировано из-за большого количества комментариев, аргументирующих мою риторику

Сравните этих двух buggers...

С#

public class MyClass
{
   public int x;

   public static void Main()
   {
      MyClass[] y = new MyClass[1000000];
      for( int idx=0; idx < 1000000; idx++)
      {
          y[idx] = new MyClass();
          y[idx].x = idx;
      }
   }
}

против этого (C)

struct MyClass
{
   int x;
}

void Main()
{
   MyClass y[1000000];
   for( int idx = 0; idx < 1000000; idx++)
   {
      y[idx].x = idx;
   }
}

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

Теперь в основном С# и Java выделяют огромные куски памяти, которые они продолжают тратить до тех пор, пока эта логика не будет выполняться быстрее. Но даже тогда, чтобы сравнить это с изменением значения целого числа, как F16 против нефтяного танкера по скорости...

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

В-третьих, это тот факт, что версия C автоматически удалит все эти объекты, когда у них закончится область действия. Но опять же это операция, которая ТОЛЬКО ИЗМЕНЯЕТ ЗНАЧЕНИЕ ЦЕЛИ. Что бы на большинстве архитектур процессоров занимало от 1 до 3 циклов процессора. Версия С# не делает этого, но когда сборщик мусора запускает и должен собирать эти элементы, я предполагаю, что мы говорим о МИЛЛИОНАх циклов процессора...

Также версия C сразу станет x86-кодом (на процессоре x86), в то время как версия С# станет первым кодом IL. Затем, позже, после выполнения, он должен быть скомпилирован JIT, который, вероятно, сам по себе принимает заказы величин дольше, а затем выполняет только версию C.

Теперь какой-то мудрый парень, вероятно, мог бы выполнить вышеупомянутый код и измерить циклы процессора. Однако это вообще не имеет никакого смысла, потому что математически это доказывает, что Управляемая версия, вероятно, займет несколько миллионов раз число циклов ЦП в качестве версии C. Поэтому я предполагаю, что сейчас мы говорим о 5-8 порядках величин медленнее в этом примере. И, конечно же, это "сфальсифицированный тест", в котором я "искал что-то, чтобы доказать свою точку зрения", однако я бросаю вызов тем, которые плохо комментировали меня на этом посту, чтобы создать образец, который НЕ выполняет быстрее на C, а также не делает 't использовать конструкции, которые вы обычно никогда не использовали бы в C из-за существующих "лучших альтернатив".

Обратите внимание, что С# и Java - это БОЛЬШИЕ языки. Я предпочитаю их в течение ЛЮБОГО ВРЕМЕНИ ДНЯ. Но НЕ потому, что они БЫСТРО. Потому что они НЕ. Они ВСЕГДА медленнее, чем C и С++. Если вы не закодированы с завязанными глазами на C или С++...

Edit

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

Даже если бы мы прошли и оптимизировали версию С# следующим образом, мы все равно закончили бы что-то несколько порядков величин медленнее, чем версия C...

Хорошая написанная часть кода C ВСЕГДА будет быстрее, чем С#, Java, Python и все, что вы управляете-языком-вы-выбираете...

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

Оба С# и Java хотя и смехотворно медленнее, чем C, и С++, если на то пошло...