Сравнение производительности C# / F#

Есть ли какое-либо сравнение производительности C#/F# в Интернете, чтобы показать правильное использование нового языка F#?

3 ответа

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

С другой стороны, в большинстве случаев вы можете достичь производительности кода F#, равной производительности кода C#. Это обычно требует кодирования в императивном или изменчивом объектно-ориентированном стиле, профиля и устранения узких мест. Вы используете те же инструменты, которые в противном случае использовали бы в C#: например.Net отражатель и профилировщик.

Тем не менее, стоит знать о некоторых высокопроизводительных конструкциях в F#, которые снижают производительность. По своему опыту я видел следующие случаи:

  • ссылки (против переменных экземпляра класса), только в коде, выполненном миллиарды раз

  • Сравнение F# (<=) и System.Collections.Generic.Comparer, например, в бинарном поиске или сортировке

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

  • Последовательности F# в два раза медленнее, чем LINQ. Это связано со ссылками и использованием функций в библиотеке F# для реализации перевода seq<_>. Это легко исправить, так как вы можете заменить модуль Seq на модуль с такими же сигнатурами, который использует Linq, PLinq или DryadLinq.

  • Tuples, F# tuple - это класс, отсортированный по куче. В некоторых случаях, например, int*int, он может заплатить за использование структуры.

  • Распределения, стоит помнить, что замыкание - это класс, созданный с помощью оператора new, который запоминает переменные, к которым осуществляется доступ. Возможно, стоит "снять" замыкание или заменить его функцией, которая явно принимает переменные, к которым обращаются, в качестве аргументов.

  • Попробуйте использовать inline для повышения производительности, особенно для общего кода.

Мой опыт - сначала писать код на F# и оптимизировать только те части, которые имеют значение. В некоторых случаях было бы легче написать медленные функции на C#, чем пытаться настроить F#. Однако с точки зрения эффективности работы программиста имеет смысл запустить / создать прототип на F#, а затем профилировать, разбирать и оптимизировать.

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

Вот несколько ссылок на эту тему (или связанных с ней):

Что я, похоже, помню из другого поста в блоге Роберта Пикеринга (или это был Скотт Хансельман?), Что в конце концов, потому что оба сидят на одной платформе, вы можете получить одинаковую производительность от обоих, но вам иногда приходится "крутить" "естественное выражение языка, чтобы сделать это. В примере, который я помню, ему пришлось крутить F#, чтобы получить сопоставимую производительность с C#...

Другие вопросы по тегам