Все ли языки, используемые в .net, одинаково эффективны? - PullRequest
4 голосов
/ 09 апреля 2010

Я знаю, что ответ на вопрос "Дача продаж" - да, но технически верно ли это.

Common Language Runtime (CLR) разработан как промежуточный язык, основанный на императивном программировании (IP), но это имеет очевидные последствия при работе с декларативным программированием (DP).

Итак, насколько эффективен язык, основанный на другой парадигме, нежели императивный стиль, при реализации в CLR?

У меня также возникает ощущение, что шаг к DP повлечет за собой дополнительный уровень абстракции, который может вообще не моделироваться, будет ли это справедливым комментарием?

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

Ответы [ 5 ]

8 голосов
/ 09 апреля 2010

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

Однако, если они выдают одинаковый выход IL, разницы нет.

7 голосов
/ 09 апреля 2010

Прежде всего, широкий спектр языков на платформе .NET определенно содержит языки, которые генерируют код с разной производительностью, поэтому не все языки одинаково производительны. Все они компилируются на один и тот же промежуточный язык (IL), но сгенерированный код может отличаться, некоторые языки могут полагаться на Reflection или динамический язык исполнения (DLR) и т. Д.

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

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

  • Небезопасный код : Вы можете использовать небезопасный код в C ++ / CLI и до некоторой степени также в C #. Это, вероятно, самый эффективный способ написания определенных операций, но вы теряете некоторые гарантии безопасности.

  • Статически типизированный, императив : Это обычный стиль программирования в C # и VB.Net, но вы также можете использовать императивный стиль из F #. Примечательно, что многие хвостовые рекурсивные функции компилируются в статически типизированный императивный код IL, поэтому это также относится к некоторым функциям F #

  • Статически типизированный, функциональный : используется большинством программ F #. Сгенерированный код в значительной степени отличается от того, что используется в категории imperative , но он по-прежнему статически типизирован, поэтому значительных потерь производительности нет. Сравнивать императив и функционал довольно сложно, так как оптимальная реализация выглядит совершенно по-разному в обеих версиях.

  • Динамически типизированный : Языки, такие как IronPython и IronRuby, используют динамический язык исполнения, который реализует динамические вызовы методов и т. Д. Это несколько медленнее, чем статически типизированный код (но DLR оптимизирован во многих отношениях). Обратите внимание, что код, написанный с использованием C # 4.0 dynamic, также попадает в эту категорию.

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

4 голосов
/ 09 апреля 2010

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

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

Сказав все это, вероятно, есть несколько общих правил, которые в основном верны:

  1. Различия в алгоритмах, вероятно, будут иметь большее значение, чем различия в компиляторе (по крайней мере, при сравнении статически типизированных языков, работающих на CLR)
  2. Для задач, которые можно легко распараллелить, языки, облегчающие использование нескольких процессоров / ядер, обеспечат простой способ ускорить ваш код.
2 голосов
/ 09 апреля 2010

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

Для языков, которые по сути являются просто синтетическими вариантами друг друга (например, C # по сравнению с VB.NET), я бы не ожидал, что будет большая разница. Но если языки слишком расходятся (например, C # и F #), тогда вы не сможете сделать правильное сравнение, потому что вы все равно не сможете написать два «эквивалентных» нетривиальных примера кода на обоих языках. .

0 голосов
/ 09 апреля 2010

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

Из большей части того, что я читал в Интернете, кажется, что управляемый компилятор C ++ делает лучшую работу по оптимизации кода IL, хотя я не видел ничего, что показало бы заметную разницу между основными языками C # / C ++ / VB.NET.

Вы даже можете попробовать скомпилировать следующее в IL и посмотреть !?

F #

#light
open System
printfn "Hello, World!\n"
Console.ReadKey(true)

C #

// Hello1.cs
public class Hello1
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, World!");
        System.Console.ReadKey(true);
    }
}
...