Естественный код F # (например, функциональный / неизменный) медленнее, чем естественный (императивный / изменяемый объектно-ориентированный) код C #. Однако этот вид F # намного короче, чем обычный код C #.
Очевидно, что есть компромисс.
С другой стороны, в большинстве случаев вы можете достичь производительности кода F #, равной производительности кода C #. Обычно для этого требуется кодирование в императивном или изменчивом объектно-ориентированном стиле, профиль и устранение узких мест Вы используете те же инструменты, которые в противном случае использовали бы в C #: например, .Net отражатель и профилировщик.
Сказав это, стоит знать о некоторых высокопроизводительных конструкциях в F #, которые снижают производительность. По своему опыту я видел следующие случаи:
ссылки (против переменных экземпляра класса), только в коде, выполненном миллиарды раз
Сравнение F # (<=) и System.Collections.Generic.Comparer, например, при бинарном поиске или сортировке </p>
хвостовые вызовы - только в определенных случаях, которые не могут быть оптимизированы компилятором или .Net времени выполнения. Как отмечено в комментариях, зависит от времени выполнения .Net.
F # последовательности в два раза медленнее, чем LINQ. Это связано с ссылками и использованием функций в библиотеке F # для реализации перевода seq <_>. Это легко исправить, поскольку вы можете заменить модуль Seq на модуль с теми же сигнатурами, которые используют Linq, PLinq или DryadLinq.
Tuples, F # tuple - это класс, отсортированный в куче. В некоторых случаях, например, int * int кортеж, который может быть платным, чтобы использовать структуру.
Распределения, стоит помнить, что замыкание - это класс, созданный с помощью оператора new, который запоминает доступные переменные. Может быть, стоит «снять» замыкание или заменить его функцией, которая явно принимает переменные, к которым обращаются, в качестве аргументов.
Попробуйте использовать inline для повышения производительности, особенно для универсального кода.
Мой опыт - сначала кодировать на F # и оптимизировать только те части, которые имеют значение. В некоторых случаях было бы легче написать медленные функции на C #, чем пытаться настроить F #. Однако с точки зрения эффективности работы программиста имеет смысл запустить / создать прототип на F #, а затем профилировать, разбирать и оптимизировать.
Суть в том, что ваш код F # может в конечном итоге работать медленнее, чем C #, из-за решений по разработке программ, но в конечном итоге можно добиться эффективности.