বনাম টাইপফ


150

কোডগুলির এই টুকরোগুলির মধ্যে কোনটি দ্রুত?

if (obj is ClassA) {}

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

সম্পাদনা: আমি সচেতন যে তারা একই কাজ করে না।


1
এখানে একটি অনুরূপ প্রশ্নের উত্তর: stackoverflow.com/questions/57701/...
swilliams

উত্তর:


167

এই প্রশ্নের উত্তর দেওয়া উচিত, এবং তারপর কিছু।

যারা দ্বিতীয় if (obj.GetType() == typeof(ClassA)) {}নিবন্ধটি পড়তে চান না তাদের জন্য দ্বিতীয় লাইনটি দ্রুত।

(সচেতন হন যে তারা একই জিনিস না করে)


1
+1 টি: অতীতে আমি বিস্ময়ের উদ্রেক কেন সি শার্প কম্পাইলার কম্পাইল করা হয়নি typeof(string).TypeHandleকরতে ldtokenCIL নির্দেশ, কিন্তু CLR জে আই টি JIT এটা যত্ন নেয় মত দেখায়। এটি এখনও কয়েকটি অতিরিক্ত অপকড নেয় তবে এটি অপটিমাইজেশনের আরও সাধারণ প্রয়োগ।
স্যাম হারওয়েল

2
Higherlogics.blogspot.ca/2013/09/… খুব পড়ুন - তারা বিভিন্ন ফ্রেমওয়ার্ক এবং x86 বনাম x 64 বনাম বিভিন্ন ধরণের ফলাফলের জন্য পরীক্ষা করে।
সিএডি

1
দয়া করে মনে রাখবেন এটি কেবল রেফারেন্স ধরণের ক্ষেত্রেই সত্য। এবং গতির পার্থক্য তাত্পর্যপূর্ণ নয়। জন্য মান ধরনের ক্ষেত্রে বক্সিং শাস্তি দেওয়া GetType, isসবসময় একটি নিরাপদ পছন্দ যতটা কর্মক্ষমতা আমাদের করেছেন। অবশ্যই তারা বিভিন্ন জিনিস করে।
নওফাল

যদি আপনি এটি পুনঃভাগে রাখেন তবে এটি "হ'ল" তে পরিবর্তিত করার পরামর্শ দেয়!
রব সেডগুইক

@ নওফাল, আমি প্রথমে বক্সিং পেনাল্টি সম্পর্কে আপনার বক্তব্য স্ট্রাক্ট ধরণের জন্য বোধগম্য করেছি, তবে আমরা যখন একটি object obj;ভেরিয়েবল পরীক্ষা করছি , এটি পরীক্ষা করার ঝুঁকির আগেই বাক্সবন্দী হয় না? এমন কোনও মামলা রয়েছে যেখানে আপনাকে কোনও কিছুর ধরণের পরীক্ষা করতে হবে এবং এটি ইতিমধ্যে কোনও বস্তু হিসাবে চিহ্নিত করা হয়নি?
রব পার্কার

193

যদি তারা একই জিনিস না করে তবে কোনটি দ্রুততর তা বিবেচনা করে? বিবৃতিগুলির পারফরম্যান্সকে বিভিন্ন অর্থের সাথে তুলনা করা খারাপ ধারণা বলে মনে হয়।

isআপনাকে জানায় যে বস্তুটি ClassAতার ধরণের বৈধব্যক্তির যে কোনও জায়গায় প্রয়োগ করে । GetType()আপনাকে সর্বাধিক উদ্ভূত প্রকারের সম্পর্কে জানায়।

একই জিনিস না।


7
এটি গুরুত্বপূর্ণ নয়, কারণ আমার ক্ষেত্রে আমি ইতিবাচক তারাও একই ফলাফল ফিরে আসে।
ইলিটরিট

37
@ [ইলিটরিট]: তারা এখনই একই ফলস্বরূপ প্রত্যাবর্তন করবে, তবে আপনি যদি পরে সাবক্লাস যোগ করেন তবে তারা পারবেন না
স্টিভেন এ। লো

13
এখনই অনুকূলিতকরণ আপনার কোডটিকে ভঙ্গুর এবং বজায় রাখা কঠিন করে তুলবে।
আইসিআর

9
আমার ক্লাস সিল করা আছে।
ইলিটরিট

26

তারা একই জিনিস না। প্রথমটি কাজ করে যদি আপত্তিটি ক্লাসএ বা ক্লাসএর কিছু উপক্লাসের হয়। দ্বিতীয়টি কেবল ক্লাসএ টাইপের বস্তুর সাথে মিলবে। দ্বিতীয়টি দ্রুততর হবে কারণ এটি ক্লাস শ্রেণিবদ্ধতা পরীক্ষা করতে হবে না।

তাদের জন্য যারা কারণটি জানতে চান তবে রেফারেন্সযুক্ত নিবন্ধটি পড়তে চান না বনাম typeof হয়


1
@ মমিতঝা আমি কিছুটা উদ্বিগ্ন যে পরীক্ষার মনোর অধীনে পরিচালিত হয়েছিল যে এটিতে নিবন্ধে জেআইটি অপ্টিমাইজেশানকে অন্তর্ভুক্ত করা হয়নি। নিবন্ধটি যেহেতু বিপরীতটি দেখায়, তাই মনে মনে প্রশ্নটি একটি উন্মুক্ত। যে কোনও ইভেন্টে, ধরণের উপর নির্ভর করে বিভিন্ন কাজ করে এমন অপারেশনগুলির পারফরম্যান্সের তুলনা করা একটি অকেজো অনুশীলন বলে মনে হয়। আপনার প্রয়োজনের সাথে মেলে এমন ক্রিয়াকলাপটি ব্যবহার করুন যা "দ্রুত" নয়
tvanfosson

16

আমি কিছু বেঞ্চমার্কিং করেছি যেখানে তারা একই কাজ করে - সিল করা প্রকারগুলি।

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. এস এ কল GetTypeকরা structধীর। ক্লাসে GetTypeসংজ্ঞায়িত করা হয় objectযা সাব টাইপগুলিতে ওভাররাইড করা যায় না এবং এইভাবে structডাকার জন্য বক্স করা দরকার GetType

  2. একটি বস্তুর উদাহরণস্বরূপ, GetTypeদ্রুত, কিন্তু খুব প্রান্তিক।

  3. জেনেরিক ধরণে, যদি Tহয় classতবে isতা আরও দ্রুত। যদি Tহয় struct, তাহলে isঅনেক দ্রুত চেয়ে GetTypeকিন্তু typeof(T)অনেক দ্রুত উভয় চেয়ে। ক্ষেত্রে Tহচ্ছে class, typeof(T)প্রকৃত অন্তর্নিহিত ধরণ থেকে তার বিভিন্ন যেহেতু নির্ভরযোগ্য নয় t.GetType

সংক্ষেপে, আপনার যদি একটি objectউদাহরণ থাকে, ব্যবহার করুন GetType। আপনার যদি জেনেরিক classটাইপ থাকে তবে ব্যবহার করুন is। আপনার যদি জেনেরিক structটাইপ থাকে তবে ব্যবহার করুন typeof(T)। আপনি যদি নিশ্চিত না হন যে জেনেরিক প্রকারটি রেফারেন্স টাইপ বা মান প্রকারের হয় তবে ব্যবহার করুন is। আপনি যদি সর্বদা একটি শৈলীর সাথে সামঞ্জস্য রাখতে চান (সিল করা ধরণের জন্য), ব্যবহার করুন is..


1
বাস্তবে, আদৌ যত্ন নেবেন না। সর্বাধিক জ্ঞানীয় যা ব্যবহার করুন।
নওফাল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.