รหัสชิ้นใดเร็วกว่ากัน
if (obj is ClassA) {}
if (obj.GetType() == typeof(ClassA)) {}
แก้ไข: ฉันทราบว่าพวกเขาไม่ได้ทำสิ่งเดียวกัน
รหัสชิ้นใดเร็วกว่ากัน
if (obj is ClassA) {}
if (obj.GetType() == typeof(ClassA)) {}
แก้ไข: ฉันทราบว่าพวกเขาไม่ได้ทำสิ่งเดียวกัน
คำตอบ:
นี่ควรจะตอบคำถามนั้นแล้วก็มีบ้าง
บรรทัดที่สองif (obj.GetType() == typeof(ClassA)) {}
นั้นเร็วกว่าสำหรับผู้ที่ไม่ต้องการอ่านบทความ
(โปรดระวังว่าพวกเขาไม่ได้ทำสิ่งเดียวกัน)
typeof(string).TypeHandle
กับldtoken
การเรียนการสอน CIL แต่ดูเหมือนว่า CLR ดูแลในร์ JIT มันยังใช้เวลาเพิ่ม opcodes เพียงไม่กี่ตัว
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
s GetType
จำเป็นที่จะต้องได้รับการบรรจุอยู่ในกล่องจะถูกเรียกว่า
ในอินสแตนซ์ของวัตถุGetType
นั้นเร็วกว่า แต่มีขอบเขตน้อยมาก
สำหรับประเภททั่วไปถ้าT
เป็นclass
แล้วis
จะเร็วกว่ามาก ถ้าT
เป็นstruct
เช่นนั้นis
จะเร็วกว่าGetType
แต่typeof(T)
เร็วกว่ามาก ในกรณีที่มีT
ความเป็นอยู่class
, ไม่น่าเชื่อถือตั้งแต่ที่แตกต่างกันจากชนิดพื้นฐานที่เกิดขึ้นจริงtypeof(T)
t.GetType
ในระยะสั้นหากคุณมีตัวอย่างเช่นการใช้งานobject
GetType
หากคุณมีทั่วไปประเภทการใช้งานclass
is
หากคุณมีทั่วไปประเภทการใช้งานstruct
หากคุณไม่แน่ใจว่าประเภททั่วไปเป็นประเภทการอ้างอิงหรือประเภทค่าใช้typeof(T)
is
หากคุณต้องการให้สอดคล้องกับสไตล์เดียวเสมอ (สำหรับประเภทที่ปิดผนึก) ให้ใช้is
..