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

Build.VERSION_CODES.LOLLIPOP теперь должен быть изменен на BuildVersionCodes.Lollipop i.e:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder, Context.Theme);
} else {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder);
}
54
задан Joan Venge 12 February 2009 в 21:34
поделиться

3 ответа

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

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

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

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

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

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

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

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

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

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

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

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

.
54
ответ дан 7 November 2019 в 08:02
поделиться

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

, Что я, кажется, помню из другого сообщения на блоге Robert Pickering (или был он Scott Hanselman?), что в конце, потому что оба сидят на той же платформе, Вы можете , получают ту же производительность от обоих, но иногда необходимо 'скручивать' естественное выражение языка, чтобы сделать так. В примере я вспоминаю, он должен был скрутить F# для получения сопоставимой производительности с C#...

11
ответ дан Benjol 7 November 2019 в 18:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: