Ответ 1
Я могу воспроизвести поведение на моей машине с повышением производительности 3 раза после добавления ключевого слова inline
.
Декомпиляция двух версий бок о бок в ILSpy дает почти идентичный код С#. Заметное различие заключается в двух тестах равенства:
// Version without inline
bool IEqualityComparer<Program.Pair<a>>.System-Collections-Generic-IEqualityComparer(Program.Pair<a> x, Program.Pair<a> y)
{
a [email protected] = [email protected];
a [email protected] = [email protected];
if (LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>([email protected], [email protected]))
{
a [email protected] = [email protected];
a [email protected] = [email protected];
return LanguagePrimitives.HashCompare.GenericEqualityIntrinsic<a>([email protected], [email protected]);
}
return false;
}
// Version with inline
bool IEqualityComparer<Program.Pair<int>>.System-Collections-Generic-IEqualityComparer(Program.Pair<int> x, Program.Pair<int> y)
{
int [email protected] = [email protected];
int [email protected] = [email protected];
if ([email protected] == [email protected])
{
int [email protected] = [email protected];
int [email protected] = [email protected];
return [email protected] == [email protected];
}
return false;
}
Общее равенство гораздо менее эффективно, чем специализированная версия.
Я также заметил огромную разницу в размере Gen 0 GC с встроенным кодом и не встроенным кодом.
Может ли кто-нибудь объяснить, почему существует такая огромная разница?
Взгляд на функцию GenericEqualityIntrinsic
в F # исходный код:
let rec GenericEqualityIntrinsic (x : 'T) (y : 'T) : bool =
fsEqualityComparer.Equals((box x), (box y))
Он делает бокс по аргументам, что объясняет значительное количество мусора в вашем первом примере. Когда GC входит в игру слишком часто, это значительно замедлит вычисления. Второй пример (используя inline
) почти не мусор, когда Pair
является структурой.
Тем не менее, это ожидаемое поведение ключевого слова inline
, когда на сайте вызова используется специализированная версия. Мое предложение всегда состоит в том, чтобы попытаться оптимизировать и измерить ваш код в тех же тестах.
Вам может быть интересен очень похожий поток Почему этот код F # настолько медленный?.