C #에서 "인라인 함수"를 어떻게 수행합니까? 나는 그 개념을 이해하지 못한다고 생각합니다. 그들은 익명의 방법을 좋아합니까? 람다 함수처럼?
참고 : 답변은 거의 대부분 함수 인라인 기능 , 즉 "함수 호출 사이트를 수신자의 본문으로 대체하는 수동 또는 컴파일러 최적화"를 처리합니다. 당신이에 관심이 있다면 익명 함수 (람다 일명) 을 참조 @ jalf의 답변 또는 어떤이 '람다'모두 계속 말하고입니다? .
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 #에서는이 작업을 수행 할 수있는 메커니즘이 없으며 지원되는 언어로 드물게 사용되어야합니다. 어딘가에서 사용해야하는 이유를 모르는 경우 사용해서는 안됩니다.
편집 : 명확히하기 위해 두 가지 중요한 이유가 있습니다.
일을 내버려두고 컴파일러가 작업을 수행하도록 한 다음 인라인이 최상의 솔루션인지 프로파일 링하고 파악하는 것이 가장 좋습니다. 물론 일부는 인라인되는 것이 합리적이지만 (특히 수학 연산자) 컴파일러가 처리하도록하는 것이 일반적으로 모범 사례입니다.
업데이트 : 당 konrad.kruczynski의 대답은 , 다음 .NET 버전의 최대 및 4.0을 포함한 마찬가지입니다.
MethodImplAttribute 클래스 를 사용 하여 메소드가 인라인 되지 않도록 할 수 있습니다 ...
[MethodImpl(MethodImplOptions.NoInlining)]
void SomeMethod()
{
// ...
}
... 반대를하고 강제 로 인라인 되도록 할 방법이 없습니다 .
GetExecutingAssembly
및 GetCallingAssembly
방법은 인라인 여부에 따라 서로 다른 결과를 제공 할 수 있습니다. 메소드가 인라인되지 않도록 강요하면 불확실성이 줄어 듭니다.
두 가지 개념을 혼합하고 있습니다. 함수 인라이닝은 의미에 영향을 미치지 않는 컴파일러 최적화입니다. 함수는 인라인 여부에 관계없이 동일하게 동작합니다.
반면에 람다 함수는 순전히 의미 개념입니다. 언어 사양에 명시된 동작을 따르는 한 구현 또는 실행 방법에 대한 요구 사항은 없습니다. 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);
이게 도움이 되길 바란다.
코드를 강제로 인라인하려는 경우가 있습니다.
예를 들어, 매우 반복적 인 블록 내에서 많은 결정이 내려지고 복잡한 결정을 내리는 복잡한 루틴이있는 경우, 그러한 결정으로 인해 비슷하지만 약간 다른 동작이 수행됩니다. 예를 들어, 정렬 알고리즘이 빠른 언어에 대한 의미 적 기준뿐만 아니라 문법에 따라 단어를 정렬하는 경우와 같이 여러 관련되지 않은 여러 기준에 따라 요소를 정렬하는 복잡한 (DB 기반이 아닌) 정렬 비교기를 고려하십시오. 인식 시스템. 소스 코드의 가독성과 모듈성을 유지하기 위해 이러한 작업을 처리하는 도우미 함수를 작성하는 경향이 있습니다.
나는 도우미 함수가 인라인되어야한다는 것을 알고 있습니다. 왜냐하면 그것이 인간이 코드를 이해할 필요가 없다면 코드가 작성되는 방식이기 때문입니다. 이 경우 확실히 함수 호출 오버 헤드가 없었는지 확인하고 싶습니다.
"이러한 것들을 내버려두고 컴파일러가 작업을 수행하도록하는 것이 가장 좋습니다."(Cody Brocious)는 완전하지 않습니다. 저는 20 년 동안 고성능 게임 코드를 프로그래밍 해 왔지만 아직 어떤 코드를 인라인 (함수)해야하는지 알 수있는 '똑똑한'컴파일러를 찾지 못했습니다. c #에 "인라인"문을 갖는 것이 유용합니다. 진실은 컴파일러가 "인라인"힌트없이 어떤 함수를 항상 인라인해야하는지 결정하는 데 필요한 모든 정보를 가지고 있지 않다는 것입니다. 함수가 작 으면 (접근 자) 자동으로 인라인 될 수 있지만 몇 줄의 코드이면 어떻게 될까요? 넌센스, 컴파일러는 알 방법이 없으며 최적화 된 코드 (알고 리트 이상)를 컴파일러에 맡길 수는 없습니다.
이 질문이 C #에 관한 것임을 알고 있습니다. 그러나 .NET에서 F #을 사용하여 인라인 함수를 작성할 수 있습니다. 참조 : F #에서`inline` 사용
람다 식은 인라인 함수입니다! C #에는 인라인과 같은 추가 속성이 없습니다.