이 코드들 중 어느 것이 더 빠릅니까?
if (obj is ClassA) {}
if (obj.GetType() == typeof(ClassA)) {}
편집 : 나는 그들이 똑같은 일을하지 않는다는 것을 알고 있습니다.
답변
이것은 그 질문에 답해야 할 것이고, 그 다음에 어떤 것이어야합니다.
두 번째 줄 if (obj.GetType() == typeof(ClassA)) {}
은 기사를 읽고 싶지 않은 사람들에게는 빠릅니다.
(그들이 똑같은 일을하지 않는다는 것을 명심하십시오)
답변
그들이 같은 일을하지 않으면 더 빠른 것이 중요합니까? 다른 의미로 진술의 성과를 비교하는 것은 나쁜 생각처럼 보입니다.
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
ISclass
, 다음is
훨씬 빠릅니다. 경우T
이며struct
, 다음is
것보다 훨씬 빠르기GetType
하지만typeof(T)
훨씬 빠르게 모두보다. 의 경우에는T
존재class
,typeof(T)
실제 기본 형태로부터 다른 이후 신뢰할 수 없습니다t.GetType
.
즉, object
인스턴스 가있는 경우을 사용하십시오 GetType
. 제네릭 class
형식 인 경우을 사용하십시오 is
. 제네릭 struct
형식 인 경우을 사용하십시오 typeof(T)
. 제네릭 형식이 참조 형식 또는 값 형식인지 확실하지 않은 경우을 사용하십시오 is
. 항상 하나의 스타일 (일관된 유형의 경우)과 일관성을 유지하려면 is
..
답변
