2009-02-26 8 views
3

.Net에서 오버로드하는 메서드와 관련된 비용이 있습니까?.Net에서 메서드 오버로드.

그래서이 있으면 추천 방법 :

Calculate (int) 
Calculate (float) 
Calculate (double) 

이러한 방법은 계산 방법에 전달 무엇을, 어떤이 오버로드 확인의 비용이 될 것입니다 기반으로 "동적"런타임에라고?

또는 하나의 Calculate를 사용하여 메서드 본문에서 차이를 만들 수도 있지만 호출 할 때마다 메서드가 메서드를 평가해야한다고 생각했습니다.

오버 헤드없이이 문제를 해결할 수있는 더 나은 방법이나 설계가 있습니까? 또는 더 나은 방법은 이러한 사례를 처리하는 가장 좋은 방법은 무엇입니까? 동일한 클래스/메소드 이름을 갖고 싶지만 다른 동작을 원합니다.

편집 : 감사. 그것이 다른 경우에 한 가지 더 말하십시오. 나는 당신이이 메소드들을위한 DLL과 C#으로 작성된 프로그램을 사용자가 UI 아이템으로 (타입을 지정하지 않고) 추가 할 수있게 해준다고 말하고 싶다. 그래서 사용자는 Calculate (5), Calculate (12.5) 등의 UI 항목을 추가하고 C# app는 이것을 실행합니다. 오버 헤드가 없습니까?

+0

이 질문은 다형성과 완전히 다른 메서드 오버로딩에 대한 것입니다. –

+0

@Cris : .NET 당 명령 당 비용은 거의 없습니다. 대부분 프레임 워크로드 시간이 문제입니다 (현재 ~ 500ms입니까?) –

+0

예 ... 오버로드와 오버라이드를 조사해야합니다. – wowest

답변

15

런타임과 관련하여 이들은 개의 다른 방법입니다. 쓰기와 같습니다 성능 문제에 관한

CalculateInt(int) 
CalculateFloat(float) 

, 매우 특별한 경우를 제외하고, 안전하게 메소드 호출 오버 헤드를 무시할 수 있습니다.

+0

편도 이를 최적화하려면 제네릭을 사용하는 것이 좋습니다. –

+0

@ John : 내 3 Calculate 메소드의 경우를 의미합니까? –

+0

@Aleris : 어떤 특별한 경우입니까? – NotMe

1

3 가지 방법이 유형에 따라 IL에서 생산됩니다. 한 가지 유형에서 다른 유형으로 캐스팅하는 경우에만 비용이 들지만 많은 양의 비용이 발생하지 않는 한 그 비용은 중요하지 않습니다. 그래서 당신은 Calculate (double)를 고수하고 거기에서 캐스팅 할 수 있습니다.

7

처음에는 프로파일 러에서 성능 문제가 있다고 말하지 않는 한 좋은 성능 향상을 위해 좋은 디자인을 희생해서는 안됩니다.

질문에 대답하기 위해 메서드 호출의 해상도는 동적이 아닙니다. 컴파일 타임에 결정되므로, 그 점에서 비용은 들지 않습니다. 유일한 비용은 매개 변수 유형에 맞는 유형의 잠재적 인 내재적 변환입니다.

9

이 질문은 다형성이 아니라 메소드 과부하에 관한 질문입니다. 필자가 아는 한 컴파일러는 전달되는 인수의 유형을 기반으로 컴파일 할 때 호출 할 메소드를 파악할 것이므로 메소드 오버로드에 대한 패널티가 없습니다.

다형성은 기본 클래스의 대체품으로 파생 형식을 사용하는 경우에만 작동합니다.

+0

명백한 것을 지적 해 주셔서 감사합니다 (냉소적이지 않고, 나는 상향 투표했습니다). 오버로딩과 다형성 사이에 중요한 차이가 있습니다. –

4

메서드 오버로드 (즉, 메서드 테이블 슬롯)는 런타임에 동적으로 확인되지 않으며 컴파일 타임에 정적으로 처리되므로 오버로드 된 메서드를 사용하는 데 비용이 들지 않습니다.

virtual 실제 구현은 파생 된 형식과 실제 형식을 기반으로 선택한 실제 메서드를 재정의 할 수있는 방법을 생각하고 있다고 가정합니다. 그러나 가상 메소드가 동일한 메소드 테이블 슬롯을 차지하므로 오버로드와 아무런 관련이 없습니다.

2

컴파일러가 컴파일 할 때 호출 할 메서드를 결정하기 때문에 런타임에 "비용"이 없습니다.생성 된 IL은 적절한 매개 변수를 취하는 메서드를 호출합니다.

내가 ''변수를 계산하기 위해 다음 호출 IL에서 이루어진다

public class Calculator 
{ 
    public void Calculate(int value) 
    { 
     //Do Something 
    } 
    public void Calculate(decimal value) 
    { 
     //Do Something 
    } 
    public void Calculate(double value) 
    { 
     //Do Something 
    } 
} 

static void Main(string[] args) 
{ 
    int i = 0; 
    Calculator calculator = new Calculator(); 
    calculator.Calculate(i); 
} 

"예 이것을 가지고 :이 방법을 지정

L_000b: callvirt instance void ConsoleApplication1.Calculator::Calculate(int32) 

통지가 입력 INT32이며 Main 메서드에서 전달 된 변수와 동일한 유형

비용이 전혀 들지 않으면 컴파일 할 때만입니다. 걱정하지 마십시오.

JaredPar으로

는 다음과 같이 언급

귀하의 질문에 오해가있다. C#에서 오버로드 된 메서드는 런타임에 동적으로 호출되지 않는 입니다. 모든 메서드 호출은 컴파일 시간에 정적으로 바인딩됩니다. 따라서 런타임에 메서드를 "검색"하지 않으므로 컴파일 시간에 미리 결정되므로 에 오버로드가 호출됩니다.

1

질문에 오해가 있습니다. C#에서 오버로드 된 메서드는 런타임에 동적으로 호출되지 않습니다. 모든 메소드 호출은 컴파일시에 정적으로 바인드됩니다. 따라서 런타임에 메서드를 "검색"하지 않으며 컴파일 시간에 미리 결정되어 오버로드가 호출됩니다.

참고 : C# 4.0 및 동적으로 약간 변경됩니다. 동적 객체를 사용하면 객체 유형에 따라 런타임에 오버로드가 선택 될 수 있습니다. C# 3.0 이하에서는 그렇지 않습니다.