Сравнение производительности C # / F # - PullRequest
53 голосов
/ 27 сентября 2008

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

Ответы [ 3 ]

50 голосов
/ 03 января 2010

Естественный код 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 #, из-за решений по разработке программ, но в конечном итоге можно добиться эффективности.

11 голосов
/ 29 сентября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...