Сравнение производительности 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# из-за решений по разработке программы, но, в конечном итоге, можно добиться эффективности.
Посмотрите эти вопросы, которые я задал недавно:
Вот несколько ссылок на эту тему (или связанных с ней):
- http://cs.hubfs.net/forums/thread/3207.aspx
- http://strangelights.com/blog/archive/2007/06/17/1588.aspx
- http://khigia.wordpress.com/2008/03/30/ocaml-vs-f-for-big-integer-surprising-performance-test/
- http://cs.hubfs.net/blogs/f_team/archive/2006/08/15/506.aspx
- http://blogs.msdn.com/jomo_fisher/
Что я, похоже, помню из другого поста в блоге Роберта Пикеринга (или это был Скотт Хансельман?), Что в конце концов, потому что оба сидят на одной платформе, вы можете получить одинаковую производительность от обоих, но вам иногда приходится "крутить" "естественное выражение языка, чтобы сделать это. В примере, который я помню, ему пришлось крутить F#, чтобы получить сопоставимую производительность с C#...