2008-10-08 15 views
118

कोड के इनमें से कौन सा टुकड़ा तेज़ है?बनाम टाइप

if (obj is ClassA) {} 

if (obj.GetType() == typeof(ClassA)) {} 

संपादित करें: मुझे पता है कि वे एक ही बात नहीं करते है।

+1

यहां एक समान प्रश्न का उत्तर दिया गया: http://stackoverflow.com/questions/57701/what-are-the-performance-characteristics -of-is-reflection-in-C# 57713 – swilliams

उत्तर

142

This should answer that question, and then some.

दूसरी पंक्ति, if (obj.GetType() == typeof(ClassA)) {}, तेज, उन है कि लेख पढ़ने के लिए नहीं करना चाहते हैं के लिए है।

+1

+1: अतीत में मैंने सोचा कि क्यों सी # कंपाइलर ने 'टाइपोफ (स्ट्रिंग) को संकलित नहीं किया है। टाइप करें' सीडीआई निर्देश 'के लिए टाइप करें। लेकिन ऐसा लगता है कि यह सीएलआर जेआईटी में इसका ख्याल रखता है। यह अभी भी कुछ अतिरिक्त ऑपकोड लेता है लेकिन यह अनुकूलन का एक अधिक सामान्यीकृत अनुप्रयोग है। –

+2

http://higherlogics.blogspot.ca/2013/09/clr-cost-of-dynamic-type-tests.html भी पढ़ें - वे व्यापक रूप से भिन्न परिणामों के साथ विभिन्न ढांचे और x86 बनाम x64 के लिए पुनः प्रयास करते हैं। –

+1

कृपया ध्यान दें कि यह केवल संदर्भ प्रकारों के लिए सही है। और गति अंतर महत्वपूर्ण नहीं है। 'गेट टाइप' के लिए मूल्य प्रकारों के मामले में मुक्केबाजी दंड को देखते हुए, प्रदर्शन हमेशा के लिए एक सुरक्षित विकल्प है, जहां तक ​​प्रदर्शन का संबंध है। बेशक वे अलग-अलग चीजें करते हैं। – nawfal

23

वे एक ही बात नहीं करते हैं। पहला काम करता है अगर ओबीजे क्लासए या क्लासए के कुछ उप-वर्ग के प्रकार का है। दूसरा वाला क्लास ए के प्रकार से मेल खाता है। दूसरा एक तेज़ होगा क्योंकि इसे कक्षा पदानुक्रम की जांच करने की आवश्यकता नहीं है।

उन लोगों के लिए जो कारण जानना चाहते हैं, लेकिन is vs typeof में संदर्भित आलेख को पढ़ना नहीं चाहते हैं।

+0

http://stackoverflow.com/q/27813304 बताता है कि 'ऑब्जेक्ट टाइप टाइप' अधिक तेज़ होगा। –

+1

@ समिति मैं थोड़ा चिंतित हूं कि क्योंकि यह परीक्षण मोनो के तहत चलाया गया था जिसमें लेख में संदर्भित जेआईटी अनुकूलन शामिल नहीं है। चूंकि लेख विपरीत दिखाता है, मेरे दिमाग में सवाल एक खुला है। किसी भी घटना में, इस प्रकार के आधार पर अलग-अलग चीजें करने वाले संचालन के प्रदर्शन की तुलना करना एक बेकार अभ्यास लगता है। उस ऑपरेशन का उपयोग करें जो आपको आवश्यक व्यवहार से मेल खाता है, न कि "तेज" – tvanfosson

153

यह ऐसा मामला है जिस, तेजी से होता है अगर वे एक ही बात नहीं करते है? विभिन्न अर्थों के साथ बयानों के प्रदर्शन की तुलना करना एक बुरा विचार लगता है।

is आपको बताता है कि क्या वस्तु ClassA को अपने प्रकार के उत्तराधिकारी में कहीं भी लागू करती है। GetType() आपको सबसे ज्यादा व्युत्पन्न प्रकार के बारे में बताता है।

वही बात नहीं है। सील प्रकार -

+6

कोई फर्क नहीं पड़ता, क्योंकि मेरे मामले में मैं सकारात्मक हूं, वे एक ही परिणाम लौटाते हैं। – ilitirit

+28

@ [ilitirit]: वे अभी वही परिणाम वापस कर देते हैं, लेकिन यदि आप बाद में उप-वर्ग जोड़ते हैं तो वे –

+10

नहीं अनुकूलित करेंगे अब आपके कोड को भंगुर बनाए रखने और बनाए रखने में मुश्किल होगी। – ICR

9

मैं कुछ बेंच मार्किंग, जहां वे भी ऐसा ही किया था।

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 { } 

अनुमान:

  1. कॉलिंग रों GetTypestruct पर धीमी है।GetTypeobject वर्ग जो उप प्रकार में ओवरराइड नहीं किया जा सकता है और इस तरह struct रों GetType के नाम से जाना बॉक्सिंग करने की आवश्यकता पर परिभाषित किया गया है।

  2. किसी ऑब्जेक्ट उदाहरण पर, GetType तेज है, लेकिन बहुत ही मामूली है।

  3. सामान्य प्रकार, यदि Tclass है, तो is तेज हो गया है। यदि Tstruct है, तो isGetType की तुलना में बहुत तेजी से होता है, लेकिन typeof(T) दोनों की तुलना में बहुत तेजी से होता है।T जा रहा है class के मामलों में, typeof(T) वास्तविक अंतर्निहित प्रकार t.GetType से अपनी अलग के बाद से विश्वसनीय नहीं है।

संक्षेप में, यदि आप एक object उदाहरण है, GetType का उपयोग करें। यदि आपके पास सामान्य class प्रकार है, तो is का उपयोग करें। यदि आपके पास सामान्य struct प्रकार है, तो typeof(T) का उपयोग करें। यदि आप अनिश्चित हैं कि सामान्य प्रकार संदर्भ प्रकार या मान प्रकार है, तो is का उपयोग करें। यदि आप हमेशा एक शैली (सीलबंद प्रकारों के लिए) के साथ संगत होना चाहते हैं, तो is का उपयोग करें ..

+0

हकीकत में, बिल्कुल परवाह नहीं है। सबसे ज्यादा समझ में आता है। – nawfal

संबंधित मुद्दे