Атрибут System.Runtime.CompilerServices.MethodImplAttribute
может использоваться для предоставления подсказок компилятору JIT о том, как обрабатывать декорированный метод. В частности, опция MethodImplOptions.AggressiveInlining
инструктирует компилятор, если это возможно, встроить метод, на который это возможно. К сожалению, компилятор F #, кажется, просто игнорирует этот атрибут при генерации IL.Применение методаImplOptions.AggressiveInlining к функциям F #
Пример: Следующий код C#
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Inc(int x) => x + 1;
переведен на
.method public hidebysig static int32 Inc(int32 x) cil managed aggressiveinlining
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: add
IL_0003: ret
}
Обратите внимание на "aggressiveinlining" флага.
Это F # код однако
[<MethodImpl(MethodImplOptions.AggressiveInlining)>]
let inc x = x + 1
становится
.method public static int32 inc(int32 x) cil managed
{
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: ret
}
Нет "aggressiveinlining". Я также попытался применить атрибут к статическим и нестационарным методам правильных классов (type ...
), но результат тот же.
Если же я применить его к пользовательскому индексатор, например, так
type Dummy =
member self.Item
with [<MethodImpl(MethodImplOptions.AggressiveInlining)>] get x = x + 1
полученный IL является
.method public hidebysig specialname instance int32 get_Item(int32 x) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.MethodImplAttribute::.ctor(valuetype [mscorlib]System.Runtime.CompilerServices.MethodImplOptions) = (01 00 00 01 00 00 00 00)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: ret
}
... хотя я не уверен в том, что эквивалентно " агрессивный ", сгенерированный компилятором C#.
Является ли это поведение желаемым/ожидаемым? Это ошибка в компиляторе F #?
(Примечание: Я знаю о F # inline
ключевого слова, но это работает только для F # клиентов моей библиотеки, а не C# потребителей.)
AFAIK Этот атрибут используется JIT: er, чтобы намекнуть, что метод должен быть встроен. Поэтому, если это правильно, вы должны проверить генерирующий машинный код.Заметка; это не так просто, как просмотр разборки в .NET, поскольку с отладчиком, работающим с JIT: er гораздо менее агрессивным. – FuleSnabel
Awww, я понимаю, что вы имеете в виду. По-видимому, в мета-данных IL отсутствует. Позвольте мне проверить это позже. – FuleSnabel
Похоже, что соблюдаются только 'PreserveSig',' Synchronized' и 'NoInlining' - см.' ComputeMethodImplAttribs' в [IlxGen.fs] (https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp /IlxGen.fs) – kvb