'var'을 사용하면 성능에 영향을 줍니까?
이전에는 왜 많은 예제가 var
키워드를 사용하는지 알 수 있었는데 익명 유형에만 필요하지만 그럼에도 불구하고 'Quicker'/ eaerier 및 'just because'코드를 작성하는 데 사용된다는 대답을 얻었습니다.
다음은 이 링크 ( "C # 3.0 - 바르하지 Objec") I 톱 var
일리노이에서 올바른 형식으로 아래로 컴파일됩니다 (당신은 기사 아래 중간에 대해 그것을 볼 것).
내 질문은 var
키워드를 사용하는 IL 코드가 얼마나 많이 사용하는지 , 그리고 코드가 어디서나 사용된다면 코드 성능에 대해 측정 가능한 수준에 가깝습니까?
var
키워드에 대한 추가 IL 코드는 없습니다 . 결과 IL은 익명이 아닌 유형에 대해 동일해야합니다. 컴파일러에서 사용하려는 유형을 파악할 수 없어서 IL을 작성할 수없는 경우 컴파일러 오류가 발생합니다.
유일한 트릭은 var
유형을 수동으로 설정하려는 경우 인터페이스 또는 상위 유형을 선택한 정확한 유형을 유추하는 것입니다.
8 년 후 업데이트
이해가 바뀌면서 이것을 업데이트해야합니다. var
메서드가 인터페이스를 반환하는 상황에서 성능에 영향을 줄 수 있다고 생각 하지만 정확한 유형을 사용했을 것입니다. 예를 들어,이 방법이 있다면 :
IList<int> Foo()
{
return Enumerable.Range(0,10).ToList();
}
메소드를 호출하려면 다음 세 줄의 코드를 고려하십시오.
List<int> bar1 = Foo();
IList<int> bar = Foo();
var bar3 = Foo();
세 가지 모두 예상대로 컴파일 및 실행됩니다. 그러나 처음 두 줄은 정확히 같지 않으며 세 번째 줄은 첫 번째 줄이 아니라 두 번째 줄과 일치합니다. 의 서명은 Foo()
을 반환하는 IList<int>
것이므로 컴파일러가 bar3
변수를 작성 하는 방법 입니다.
성능 관점에서는 대부분 눈치 채지 못할 것입니다. 그러나 세 번째 라인의 성능이 첫 번째 라인의 성능만큼 빠르지 않은 상황이 있습니다 . bar3
변수 를 계속 사용하면 컴파일러가 같은 방식으로 메서드 호출을 전달하지 못할 수 있습니다.
지터가이 차이를 지울 수는 있지만 가능하지는 않습니다. 일반적으로 var
성능 측면에서 여전히 비 인수자로 간주해야 합니다. dynamic
변수를 사용하는 것과는 전혀 다릅니다. 그러나 결코 변화를 일으키지 않는다고 말하면 그것을 과장하는 것일 수 있습니다.
Joel이 말했듯이 컴파일러는 var 유형이 무엇인지 컴파일 타임에 해결 합니다. 실제로 키 입력을 저장하기 위해 컴파일러가 수행하는 트릭입니다. 예를 들어
var s = "hi";
에 의해 대체
string s = "hi";
IL이 생성되기 전에 컴파일러에 의해 생성 된 IL은 문자열을 입력 한 것과 정확히 동일합니다.
아무도 아직 반사판을 언급하지 않았 듯이 ...
다음 C # 코드를 컴파일하는 경우 :
static void Main(string[] args)
{
var x = "hello";
string y = "hello again!";
Console.WriteLine(x);
Console.WriteLine(y);
}
그런 다음 반사기를 사용하면 다음과 같은 이점이 있습니다.
// Methods
private static void Main(string[] args)
{
string x = "hello";
string y = "hello again!";
Console.WriteLine(x);
Console.WriteLine(y);
}
따라서 런타임 성능에 전혀 영향을 미치지 않습니다.
다음 방법의 경우 :
private static void StringVsVarILOutput()
{
var string1 = new String(new char[9]);
string string2 = new String(new char[9]);
}
IL 출력은 다음과 같습니다.
{
.method private hidebysig static void StringVsVarILOutput() cil managed
// Code size 28 (0x1c)
.maxstack 2
.locals init ([0] string string1,
[1] string string2)
IL_0000: nop
IL_0001: ldc.i4.s 9
IL_0003: newarr [mscorlib]System.Char
IL_0008: newobj instance void [mscorlib]System.String::.ctor(char[])
IL_000d: stloc.0
IL_000e: ldc.i4.s 9
IL_0010: newarr [mscorlib]System.Char
IL_0015: newobj instance void [mscorlib]System.String::.ctor(char[])
IL_001a: stloc.1
IL_001b: ret
} // end of method Program::StringVsVarILOutput
분명히, 그것은 게으른 코딩 스타일입니다. 선택의 여지가있는 기본 유형을 선호합니다. 코드 / 디버그 시간에 정확히 맞는 내용을 쓰고 읽고 있는지 확인하기 위해 "노이즈"를 조금 더 살펴 보겠습니다. * 어깨를 으쓱하다 *
C # 컴파일러는 var
컴파일시 변수 의 실제 유형을 유추합니다 . 생성 된 IL에는 차이가 없습니다.
나는 당신이 읽은 것을 올바르게 이해했다고 생각하지 않습니다. 올바른 유형으로 컴파일되면 차이 가 없습니다. 내가 이것을 할 때 :
var i = 42;
컴파일러 는 그것이 int 임을 알고 내가 작성한 것처럼 코드를 생성합니다.
int i = 42;
링크 한 게시물이 말한 대로 동일한 유형으로 컴파일 됩니다. 런타임 검사 또는 추가 코드가 필요한 것은 아닙니다. 컴파일러는 유형이 무엇인지 파악하고 사용합니다.
var를 사용하면 런타임 성능 비용이 없습니다. 비록 컴파일러가 형식을 유추해야하기 때문에 컴파일 성능 비용이 있다고 생각하지만 무시할 수 있습니다.
컴파일러에서 자동 형식 유추를 수행 할 수 있으면 성능에 문제가 없습니다. 둘 다 동일한 코드를 생성합니다
var x = new ClassA();
ClassA x = new ClassA();
그러나 유형을 동적으로 구성하는 경우 (LINQ ...) var
유일한 질문이며 페널티가 무엇인지 말하기 위해 비교할 다른 메커니즘이 있습니다.
나는 항상 웹 기사 나 가이드 글에 var라는 단어를 사용합니다.
온라인 기사의 텍스트 편집기 너비가 작습니다.
내가 이것을 쓰면 :
SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();
위에서 렌더링 된 프리 코드 텍스트가 너무 길어서 상자 밖으로 흘러 나가면 숨겨집니다. 전체 구문을 보려면 독자가 오른쪽으로 스크롤해야합니다.
그렇기 때문에 항상 웹 기사 작성에 키워드 var를 사용합니다.
var coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();
렌더링 된 프리 코드 전체가 화면에 딱 맞습니다.
실제로 객체를 선언하기 위해 var를 거의 사용하지 않으며 객체를 더 빨리 선언하기 위해 intellisense에 의존합니다.
예:
SomeCoolNamespace.SomeCoolObject coolObject = new SomeCoolNamespace.SomeCoolObject();
그러나 메소드에서 객체를 반환하기 위해 var를 사용하여 코드를 더 빨리 작성합니다.
예:
var coolObject = GetCoolObject(param1, param2);
"var"은 사람들이 좋아하거나 싫어하는 지역 중 하나입니다. 지역과 달리 익명 클래스를 만들 때는 var가 반드시 필요합니다.
나에게 var는 다음과 같이 직접 객체를 업데이트 할 때 의미가 있습니다.
var dict = new Dictionary<string, string>();
즉, 당신은 쉽게 할 수 있습니다 :
Dictionary<string, string> dict =
새롭고 지능이 당신을 위해 나머지를 채울 것입니다.
특정 인터페이스로만 작업하려는 경우 호출하는 메서드가 인터페이스를 직접 반환하지 않으면 var를 사용할 수 없습니다.
Resharper는 "var"을 사용하는 편에있는 것 같습니다. 이렇게하면 더 많은 사람들이 그렇게 할 수 있습니다. 그러나 메서드를 호출하는 경우 읽기가 어렵고 이름으로 무엇이 반환되는지 명확하지 않습니다.
var 자체는 속도를 늦추지는 않지만 많은 사람들이 생각하지 않는 한 가지주의 사항이 있습니다. 그렇다면 var result = SomeMethod();
코드가 다양한 메소드 또는 속성 또는 무엇이든 호출 할 수있는 일종의 결과를 기대합니다. 경우 SomeMethod()
다른 유형의 정의를 변경하지만 여전히 다른 코드가 기다리고 있었다 계약을 만나, 당신은 단지 (NO 단위 / 통합 테스트의 경우, 물론) 정말 불쾌한 버그를 만들었습니다.
상황에 따라 다릅니다. 사용하려고하면이 코드가 표시됩니다.
식이 "OBJECT"로 변환되어 성능이 크게 저하되지만 격리 된 문제입니다.
암호:
public class Fruta
{
dynamic _instance;
public Fruta(dynamic obj)
{
_instance = obj;
}
public dynamic GetInstance()
{
return _instance;
}
}
public class Manga
{
public int MyProperty { get; set; }
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
public int MyProperty3 { get; set; }
}
public class Pera
{
public int MyProperty { get; set; }
public int MyProperty1 { get; set; }
public int MyProperty2 { get; set; }
}
public class Executa
{
public string Exec(int count, int value)
{
int x = 0;
Random random = new Random();
Stopwatch time = new Stopwatch();
time.Start();
while (x < count)
{
if (value == 0)
{
var obj = new Pera();
}
else if (value == 1)
{
Pera obj = new Pera();
}
else if (value == 2)
{
var obj = new Banana();
}
else if (value == 3)
{
var obj = (0 == random.Next(0, 1) ? new Fruta(new Manga()).GetInstance() : new Fruta(new Pera()).GetInstance());
}
else
{
Banana obj = new Banana();
}
x++;
}
time.Stop();
return time.Elapsed.ToString();
}
public void ExecManga()
{
var obj = new Fruta(new Manga()).GetInstance();
Manga obj2 = obj;
}
public void ExecPera()
{
var obj = new Fruta(new Pera()).GetInstance();
Pera obj2 = obj;
}
}
위의 결과는 ILSPY입니다.
public string Exec(int count, int value)
{
int x = 0;
Random random = new Random();
Stopwatch time = new Stopwatch();
time.Start();
for (; x < count; x++)
{
switch (value)
{
case 0:
{
Pera obj5 = new Pera();
break;
}
case 1:
{
Pera obj4 = new Pera();
break;
}
case 2:
{
Banana obj3 = default(Banana);
break;
}
case 3:
{
object obj2 = (random.Next(0, 1) == 0) ? new Fruta(new Manga()).GetInstance() : new Fruta(new Pera()).GetInstance();
break;
}
default:
{
Banana obj = default(Banana);
break;
}
}
}
time.Stop();
return time.Elapsed.ToString();
}
이 코드를 실행하려면 다음 코드를 사용하여 시간 차이를 얻으십시오.
static void Main(string[] args)
{
Executa exec = new Executa();
int x = 0;
int times = 4;
int count = 100000000;
int[] intanceType = new int[4] { 0, 1, 2, 3 };
while(x < times)
{
Parallel.For(0, intanceType.Length, (i) => {
Console.WriteLine($"Tentativa:{x} Tipo de Instancia: {intanceType[i]} Tempo Execução: {exec.Exec(count, intanceType[i])}");
});
x++;
}
Console.ReadLine();
}
문안 인사
참고 URL : https://stackoverflow.com/questions/356846/will-using-var-affect-performance
'Programing' 카테고리의 다른 글
루비에서 콜론 연산자는 무엇입니까? (0) | 2020.04.22 |
---|---|
Dockerfile에서 이미지 이름을 설정하는 방법은 무엇입니까? (0) | 2020.04.21 |
git pull을 취소하는 방법? (0) | 2020.04.21 |
jQuery Datepicker onchange 이벤트 문제 (0) | 2020.04.21 |
string.Equals ()와 == 연산자가 실제로 동일합니까? (0) | 2020.04.21 |