[C#] C #의 인라인 함수?

C #에서 “인라인 함수”를 어떻게 수행합니까? 나는 그 개념을 이해하지 못한다고 생각합니다. 그들은 익명의 방법을 좋아합니까? 람다 함수처럼?

참고 : 답변은 거의 대부분 함수 인라인 기능 , 즉 “함수 호출 사이트를 수신자의 본문으로 대체하는 수동 또는 컴파일러 최적화”를 처리합니다. 당신이에 관심이 있다면 익명 함수 (람다 일명) 을 참조 @ jalf의 답변 또는 어떤이 ‘람다’모두 계속 말하고입니다? .



답변

마지막으로 .NET 4.5에서 CLR을 사용하면 값을 사용하여 1 개의 메소드 인라인 을 암시 / 제안 할 수 있습니다 MethodImplOptions.AggressiveInlining. 모노 트렁크 (오늘 커밋)에서도 사용할 수 있습니다.

// The full attribute usage is in mscorlib.dll,
// so should not need to include extra references
using System.Runtime.CompilerServices;

...

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void MyMethod(...)

1 . 이전에는 “힘”이 사용되었습니다. 몇 개의 downvotes가 있었으므로 용어를 명확히하려고 노력할 것입니다. 의견 및 문서에서와 같이, The method should be inlined if possible.특히 Mono (개방형)를 고려할 때 인라인 또는보다 일반적인 것 (가상 함수와 같은)을 고려할 때 일부 특정 기술적 제한이 있습니다. 전반적으로 그렇습니다. 이것은 컴파일러에 대한 힌트이지만, 그것이 요청 된 것 같습니다.


답변

인라인 메소드는 단순히 함수 코드가 호출자에게 롤링되는 컴파일러 최적화입니다.

C #에서는이 작업을 수행 할 수있는 메커니즘이 없으며 지원되는 언어로 드물게 사용되어야합니다. 어딘가에서 사용해야하는 이유를 모르는 경우 사용해서는 안됩니다.

편집 : 명확히하기 위해 두 가지 중요한 이유가 있습니다.

  1. 필요하지 않은 경우 인라인을 사용하여 대규모 바이너리를 쉽게 만들 수 있습니다.
  2. 컴파일러는 성능 관점에서 무언가 인라인되어야 할 때보 다 더 잘 알고 있습니다.

일을 내버려두고 컴파일러가 작업을 수행하도록 한 다음 인라인이 최상의 솔루션인지 프로파일 링하고 파악하는 것이 가장 좋습니다. 물론 일부는 인라인되는 것이 합리적이지만 (특히 수학 연산자) 컴파일러가 처리하도록하는 것이 일반적으로 모범 사례입니다.


답변

업데이트 :konrad.kruczynski의 대답은 , 다음 .NET 버전의 최대 및 4.0을 포함한 마찬가지입니다.

MethodImplAttribute 클래스사용 하여 메소드가 인라인 되지 않도록 할 수 있습니다 …

[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
    // ...
}

… 반대를하고 강제 로 인라인 되도록 할 방법이 없습니다 .


답변

두 가지 개념을 혼합하고 있습니다. 함수 인라이닝은 의미에 영향을 미치지 않는 컴파일러 최적화입니다. 함수는 인라인 여부에 관계없이 동일하게 동작합니다.

반면에 람다 함수는 순전히 의미 개념입니다. 언어 사양에 명시된 동작을 따르는 한 구현 또는 실행 방법에 대한 요구 사항은 없습니다. JIT 컴파일러가 느낌이 들거나 그렇지 않은 경우 인라인 될 수 있습니다.

C #에는 인라인 키워드가 없습니다. 일반적으로 JIT 언어로 컴파일러에 맡길 수있는 최적화이기 때문입니다. JIT 컴파일러는 런타임 통계에 액세스하여 코드를 작성할 때보 다 훨씬 효율적으로 인라인 할 항목을 결정할 수 있습니다. 컴파일러가 결정하면 함수가 인라인되고 어떤 식 으로든 할 수있는 일이 없습니다. 🙂


답변

C ++ 의미에서 인라인 함수를 의미합니까? 일반 함수의 내용이 자동으로 호출 사이트에 인라인으로 복사됩니까? 최종 결과는 함수를 호출 할 때 실제로 함수 호출이 발생하지 않는다는 것입니다.

예:

inline int Add(int left, int right) { return left + right; }

그렇다면 no, 이것에 해당하는 C #은 없습니다.

아니면 다른 함수 내에 선언 된 함수를 의미합니까? 그렇다면 C #은 익명 메서드 나 람다 식을 통해이를 지원합니다.

예:

static void Example() {
  Func<int,int,int> add = (x,y) => x + y;
  var result = add(4,6);  // 10
}


답변

Cody는 옳지 만 인라인 함수가 무엇인지에 대한 예를 제공하고 싶습니다.

이 코드가 있다고 가정 해 봅시다.

private void OutputItem(string x)
{
    Console.WriteLine(x);

    //maybe encapsulate additional logic to decide 
    // whether to also write the message to Trace or a log file
}

public IList<string> BuildListAndOutput(IEnumerable<string> x)
{  // let's pretend IEnumerable<T>.ToList() doesn't exist for the moment
    IList<string> result = new List<string>();

    foreach(string y in x)
    {
        result.Add(y);
        OutputItem(y);
    }
    return result;
}

컴파일러 적시 최적화이 대신 같은 코드를 작성 것처럼이 될 것이라고 때문에, 스택에 OutputItem ()로 전화를 걸 반복하지 않도록 코드를 변경하도록 선택할 수 있습니다 :

public IList<string> BuildListAndOutput(IEnumerable<string> x)
{
    IList<string> result = new List<string>();

    foreach(string y in x)
    {
        result.Add(y);

        // full OutputItem() implementation is placed here
        Console.WriteLine(y);
    }

    return result;
}

이 경우 OutputItem () 함수가 인라인되었다고 말할 수 있습니다. 다른 곳에서도 OutputItem ()을 호출하더라도이 작업이 수행 될 수 있습니다.

인라인 될 가능성이 더 높은 시나리오를 표시하도록 편집되었습니다.


답변

예, 정확히 유일한 차이점은 값을 반환한다는 사실입니다.

단순화 (표현식을 사용하지 않음) :

List<T>.ForEach 조치를 취하지 만 리턴 결과를 기대하지 않습니다.

따라서 Action<T>대의원이 충분할 것입니다.

List<T>.ForEach(param => Console.WriteLine(param));

말하는 것과 같습니다.

List<T>.ForEach(delegate(T param) { Console.WriteLine(param); });

차이점은 매개 변수 유형과 대리자 거부가 사용법에 의해 추론되고 간단한 인라인 방법에서는 괄호가 필요하지 않다는 것입니다.

어디로

List<T>.Where 결과를 기대하면서 함수를 취합니다.

따라서 Function<T, bool>예상됩니다 :

List<T>.Where(param => param.Value == SomeExpectedComparison);

이는 다음과 같습니다.

List<T>.Where(delegate(T param) { return param.Value == SomeExpectedComparison; });

이 메소드를 인라인으로 선언하고 변수 IE에 할당 할 수도 있습니다.

Action myAction = () => Console.WriteLine("I'm doing something Nifty!");

myAction();

또는

Function<object, string> myFunction = theObject => theObject.ToString();

string myString = myFunction(someObject);

이게 도움이 되길 바란다.