首页 > 解决方案 > MethodImplOptions.AggressiveInlining 是否可以防止昂贵的参数在不使用时进行评估?

问题描述

说我有一个功能Log

void Log(string message, LogLevel logLevel) {
    if (logLevel >= chosenLogLevel)
        Console.WriteLine(message);
}

我用一个昂贵的评估参数来调用它:

Log(SlowFunction(), someLogLevel);

如果我要申请MethodImplOptions.AggressiveInlining,Log是否会SlowFunction被调用 iflogLevel小于chosenLogLevel?

标签: c#

解决方案


内联在这里无济于事

您当前的代码是这样的

void Log(string message, LogLevel logLevel) {
    if (logLevel >= chosenLogLevel)
        Console.WriteLine(message);
}

void Foo()
{
    Log(SlowFunction(), someLogLevel);
}

内联后变成:

void Foo()
{
    var message = SlowFunction();
    var logLevel = someLogLevel;
    if (logLevel >= chosenLogLevel)
        Console.WriteLine(message);
}

logLevel然后可以进一步内联,但SlowFunction()根据定义必须在检查之前调用。


避免这种情况的一种方法是传递messageFunc<string>

void Log(Func<string> message, LogLevel logLevel) {
    if (logLevel >= chosenLogLevel)
        Console.WriteLine(message());
}

void Foo()
{
    Log(SlowFunction, someLogLevel);
}

推荐阅读