답변:
이것은 그 질문에 답해야 할 것이고, 그 다음에 어떤 것이어야합니다.
두 번째 줄 if (obj.GetType() == typeof(ClassA)) {}
은 기사를 읽고 싶지 않은 사람들에게는 빠릅니다.
(그들이 똑같은 일을하지 않는다는 것을 명심하십시오)
typeof(string).TypeHandle
받는 ldtoken
CIL 명령하지만, CLR은 JIT에서 처리합니다 것 같습니다. 여전히 몇 가지 추가 opcode가 필요하지만 최적화의보다 일반적인 응용 프로그램입니다.
GetType
, is
성능에 관한 한 지금까지처럼 안전한 선택은 항상있다. 물론 그들은 다른 일을합니다.
object obj;
변수를 테스트하고 있다고 가정 할 때, 이것이 테스트 될 때 이미 박스되지 않습니까? 무언가의 유형을 테스트해야하는데 이미 오브젝트로 박스 화되어 있지 않은 경우가 있습니까?
그들이 같은 일을하지 않으면 더 빠른 것이 중요합니까? 다른 의미로 진술의 성과를 비교하는 것은 나쁜 생각처럼 보입니다.
is
객체 ClassA
가 유형 계층의 어느 곳에서나 구현되는지 알려줍니다 . GetType()
가장 파생 된 유형에 대해 알려줍니다.
같은 것이 아닙니다.
그들은 같은 일을하지 않습니다. 첫 번째는 obj가 ClassA 유형이거나 ClassA의 일부 서브 클래스 인 경우 작동합니다. 두 번째는 ClassA 유형의 객체와 만 일치합니다. 두 번째는 클래스 계층 구조를 확인할 필요가 없기 때문에 더 빠릅니다.
이유를 알고 싶지만 다음에 언급 된 기사를 읽고 싶지 않은 사람들을 위해 vs typeof 입니다.
나는 그들이 밀봉 유형을 동일하게하는 벤치마킹을했습니다.
var c1 = "";
var c2 = typeof(string);
object oc1 = c1;
object oc2 = c2;
var s1 = 0;
var s2 = '.';
object os1 = s1;
object os2 = s2;
bool b = false;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
b = c1.GetType() == typeof(string); // ~60ms
b = c1 is string; // ~60ms
b = c2.GetType() == typeof(string); // ~60ms
b = c2 is string; // ~50ms
b = oc1.GetType() == typeof(string); // ~60ms
b = oc1 is string; // ~68ms
b = oc2.GetType() == typeof(string); // ~60ms
b = oc2 is string; // ~64ms
b = s1.GetType() == typeof(int); // ~130ms
b = s1 is int; // ~50ms
b = s2.GetType() == typeof(int); // ~140ms
b = s2 is int; // ~50ms
b = os1.GetType() == typeof(int); // ~60ms
b = os1 is int; // ~74ms
b = os2.GetType() == typeof(int); // ~60ms
b = os2 is int; // ~68ms
b = GetType1<string, string>(c1); // ~178ms
b = GetType2<string, string>(c1); // ~94ms
b = Is<string, string>(c1); // ~70ms
b = GetType1<string, Type>(c2); // ~178ms
b = GetType2<string, Type>(c2); // ~96ms
b = Is<string, Type>(c2); // ~65ms
b = GetType1<string, object>(oc1); // ~190ms
b = Is<string, object>(oc1); // ~69ms
b = GetType1<string, object>(oc2); // ~180ms
b = Is<string, object>(oc2); // ~64ms
b = GetType1<int, int>(s1); // ~230ms
b = GetType2<int, int>(s1); // ~75ms
b = Is<int, int>(s1); // ~136ms
b = GetType1<int, char>(s2); // ~238ms
b = GetType2<int, char>(s2); // ~69ms
b = Is<int, char>(s2); // ~142ms
b = GetType1<int, object>(os1); // ~178ms
b = Is<int, object>(os1); // ~69ms
b = GetType1<int, object>(os2); // ~178ms
b = Is<int, object>(os2); // ~69ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
제네릭 형식을 테스트하는 제네릭 함수 :
static bool GetType1<S, T>(T t)
{
return t.GetType() == typeof(S);
}
static bool GetType2<S, T>(T t)
{
return typeof(T) == typeof(S);
}
static bool Is<S, T>(T t)
{
return t is S;
}
사용자 정의 유형도 시도했지만 결과는 일관되었습니다.
var c1 = new Class1();
var c2 = new Class2();
object oc1 = c1;
object oc2 = c2;
var s1 = new Struct1();
var s2 = new Struct2();
object os1 = s1;
object os2 = s2;
bool b = false;
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
b = c1.GetType() == typeof(Class1); // ~60ms
b = c1 is Class1; // ~60ms
b = c2.GetType() == typeof(Class1); // ~60ms
b = c2 is Class1; // ~55ms
b = oc1.GetType() == typeof(Class1); // ~60ms
b = oc1 is Class1; // ~68ms
b = oc2.GetType() == typeof(Class1); // ~60ms
b = oc2 is Class1; // ~68ms
b = s1.GetType() == typeof(Struct1); // ~150ms
b = s1 is Struct1; // ~50ms
b = s2.GetType() == typeof(Struct1); // ~150ms
b = s2 is Struct1; // ~50ms
b = os1.GetType() == typeof(Struct1); // ~60ms
b = os1 is Struct1; // ~64ms
b = os2.GetType() == typeof(Struct1); // ~60ms
b = os2 is Struct1; // ~64ms
b = GetType1<Class1, Class1>(c1); // ~178ms
b = GetType2<Class1, Class1>(c1); // ~98ms
b = Is<Class1, Class1>(c1); // ~78ms
b = GetType1<Class1, Class2>(c2); // ~178ms
b = GetType2<Class1, Class2>(c2); // ~96ms
b = Is<Class1, Class2>(c2); // ~69ms
b = GetType1<Class1, object>(oc1); // ~178ms
b = Is<Class1, object>(oc1); // ~69ms
b = GetType1<Class1, object>(oc2); // ~178ms
b = Is<Class1, object>(oc2); // ~69ms
b = GetType1<Struct1, Struct1>(s1); // ~272ms
b = GetType2<Struct1, Struct1>(s1); // ~140ms
b = Is<Struct1, Struct1>(s1); // ~163ms
b = GetType1<Struct1, Struct2>(s2); // ~272ms
b = GetType2<Struct1, Struct2>(s2); // ~140ms
b = Is<Struct1, Struct2>(s2); // ~163ms
b = GetType1<Struct1, object>(os1); // ~178ms
b = Is<Struct1, object>(os1); // ~64ms
b = GetType1<Struct1, object>(os2); // ~178ms
b = Is<Struct1, object>(os2); // ~64ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
그리고 유형 :
sealed class Class1 { }
sealed class Class2 { }
struct Struct1 { }
struct Struct2 { }
추론:
호출 GetType
에 struct
의 것은 느립니다. GetType
은 object
하위 유형으로 재정의 할 수없는 클래스에서 정의 되므로 struct
호출하려면 boxed해야합니다 GetType
.
객체 인스턴스에서는 GetType
더 빠르지 만 매우 미미합니다.
제네릭 형식에, 경우 T
IS class
, 다음 is
훨씬 빠릅니다. 경우 T
이며 struct
, 다음 is
것보다 훨씬 빠르기 GetType
하지만 typeof(T)
훨씬 빠르게 모두보다. 의 경우에는 T
존재 class
, typeof(T)
실제 기본 형태로부터 다른 이후 신뢰할 수 없습니다 t.GetType
.
즉, object
인스턴스 가있는 경우을 사용하십시오 GetType
. 제네릭 class
형식 인 경우을 사용하십시오 is
. 제네릭 struct
형식 인 경우을 사용하십시오 typeof(T)
. 제네릭 형식이 참조 형식 또는 값 형식인지 확실하지 않은 경우을 사용하십시오 is
. 항상 하나의 스타일 (일관된 유형의 경우)과 일관성을 유지하려면 is
..