2009-12-15 1 views
0

new Stuff().DoStuff();보다 빠르며 var x = new Stuff(); x.DoStuff();입니까?은 var x = new Stuff()입니다. x.DoStuff(); 새로운 Stuff()보다 빠릅니다. DoStuff();

이유는 모르지만 코드에서 첫 번째 방법이 더 빠르다는 것을 알았습니다. 누가 더 빠르고 그 중 하나인지 알 수 있습니까?

+3

나는 컴파일러에서 어쨌든 똑같은 일을하고 있다고 확신한다. 둘 다 IL을 비교해 봤어? –

+1

어떻게 측정 했습니까? 작은 코드 조각을 측정하는 것은 상당히 어렵다고 생각합니다. DoStuff 메소드를 병목 현상이있는 경우에만 최적화하는 것이 좋습니다. – jmservera

+1

그런 간결한 코드 예제에서, 어떻게 선언되는지에 대한 표시가 없기 때문에 합리적인 벤치 마크를 설계하는 방법을 알 수 없습니다. 그런데 나는 투표하지 않았다. 질문을 좀 더 정교하게 만들고 코드 샘플을 더 노골적인 것으로 생각해보십시오. – BillW

답변

9

사실 두 번째 작업은 더 적은 작업을 수행하므로 더 빨라야합니다. 의 예를 들어이 프로그램을 보자 :

class Program 
{ 
    public void Foo() { } 

    static void Main() 
    {} 

    static void Method1() 
    { 
     var x = new Program(); 
     x.Foo(); 
    } 

    static void Method2() 
    { 
     new Program().Foo(); 
    } 
} 

여기 방법 항목과 방법 2가 릴리스 모드로 컴파일 할 때처럼 보이게하는 방법은 다음과 같습니다 마이크로 최적화 문제의이 종류의 질문해서는 안됩니다 물론

.method private hidebysig static void Method1() cil managed 
{ 
    .maxstack 1 
    .locals init (
     [0] class Program x) 
    L_0000: newobj instance void Program::.ctor() 
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: callvirt instance void Program::Foo() 
    L_000c: ret 
} 

.method private hidebysig static void Method2() cil managed 
{ 
    .maxstack 8 
    L_0000: newobj instance void Program::.ctor() 
    L_0005: call instance void Program::Foo() 
    L_000a: ret 
} 

.

+5

또한 JIT 컴파일러는 어쨌든 그 IL에서 동일한 기계 코드를 생성 할 것이다. –

+2

+1 : "물론 이런 종류의 미세 최적화 질문을해서는 안됩니다." 질문에 -1. – Andrew

+1

모든 최적화가 가능합니까? 나는 컴파일러가 때때로 변수를 제거하는 것을 보아서 동일하게 만든다. –

3

IMO 속도는 두 버전에서 모두 동일해야합니다. 아마도 귀하의 벤치 마크에 결함이 있습니까?

4

에서보세요 사용 이것은 그들이 생산 IL 코드 :

new Stuff().DoStuff();는 :

// Code size  11 (0xb) 
    .maxstack 8 
    IL_0000: newobj  instance void ConsoleApplication1.Stuff::.ctor() 
    IL_0005: call  instance void ConsoleApplication1.Stuff::DoStuff() 
    IL_000a: ret 

var x = new Stuff(); x.DoStuff(); : 두 변형 위에 1,000,000 회 반복하면

// Code size  13 (0xd) 
    .maxstack 1 
    .locals init ([0] class ConsoleApplication1.Stuff x) 
    IL_0000: newobj  instance void ConsoleApplication1.Stuff::.ctor() 
    IL_0005: stloc.0 
    IL_0006: ldloc.0 
    IL_0007: callvirt instance void ConsoleApplication1.Stuff::DoStuff() 
    IL_000c: ret 

상기 new Stuff().DoStuff(); 버전은 약 20 % 미만의 시간을 사용한다. 내가 걱정할 것은 아무것도 없다. (차이는 1 백만 회 반복에서 0.8 밀리 초).

+4

그래, 최소한의 차이점이 내게 중요하다면, 처음에는 .NET을 사용하지 않을 것이라고 생각한다. – dan

1

첫 번째 버전은 현지인에게 x에 대한 참조를 저장해야하며, 후자의 버전에서는 추가 지침을 사용하지 않고는 수행 할 수 없습니다. 그러나 코드를 조금만 변경해도 성능이 변경됩니다.

JIT의 효율성을 과소 평가하지 마십시오. JIT는 컴파일 속도와 생성 된 코드의 효율성을 조화시켜야합니다. JIT'er는 기계 코드 생성을위한 최고의 응용 프로그램이 아닙니다. CIL 코드에서.

관련 문제