ঠিক আছে, প্রোফাইলার কখনও মিথ্যা বলে না।
যেহেতু আমার 18-2 টি ধরণের একটি স্থিতিশীল শ্রেণিবিন্যাস রয়েছে যা খুব বেশি পরিবর্তন হচ্ছে না, তাই আমি ভাবছিলাম যে যদি কেবল একজন সাধারণ এনাম'ড সদস্য ব্যবহার করে কৌশলটি সম্পাদন করা যায় এবং আরটিটিআইয়ের "উচ্চ" ব্যয়টি এড়ানো যায়। আরটিটিআই আসলে যে if
বিবৃতি দিয়েছিল তার চেয়ে বেশি ব্যয়বহুল হলে আমার সন্দেহ হয়েছিল। ছেলে ওহে ছেলে, তাই না।
এটা পরিনত হয় যে RTTI হয় দামী আরো অনেক কিছু একটি সমতুল্য চেয়ে ব্যয়বহুল if
বিবৃতি অথবা একটি সহজ switch
সি ++ একটি আদিম পরিবর্তনশীল উপর। সুতরাং S.Lott এর উত্তর সম্পূর্ণরূপে সঠিক নয়, সেখানে হয় RTTI জন্য অতিরিক্ত খরচ নেই, এবং এটা না শুধু কারণে একটি থাকার if
বিবৃতি মিশ্রণ মধ্যে। এটি আরটিটিআইয়ের জন্য খুব ব্যয়বহুল due
এই পরীক্ষাটি অ্যাপল এলএলভিএম 5.0 সংকলকটিতে স্টক অপ্টিমাইজেশন চালু (ডিফল্ট রিলিজ মোড সেটিংস) দিয়ে করা হয়েছিল।
সুতরাং, আমার 2 টিরও কম ফাংশন রয়েছে, যার প্রতিটিই 1) আরটিটিআই বা 2) কোনও সাধারণ স্যুইচ এর মাধ্যমে কোনও সামগ্রীর কংক্রিটের ধরণের চিত্র বের করে। এটি 50,000,000 বার করে। আরও অ্যাডো না করে, আমি আপনার কাছে 50,000,000 রানের আপেক্ষিক রানটাইম উপস্থাপন করছি।
এটা ঠিক, রানটাইমের 94% সময় dynamicCasts
নিয়েছে । যদিও ব্লক শুধুমাত্র গ্রহণ 3.3% ।regularSwitch
দীর্ঘ গল্পের সংক্ষিপ্তসার: যদি আপনি enum
নীচের মতো হুক-ইন করার জন্য শক্তির ঝাঁকুনি দিতে পারেন তবে আমি সম্ভবত এটির পরামর্শ দিই, যদি আপনার আরটিটিআই করার দরকার হয় এবং অভিনয়টি সবচেয়ে গুরুত্বপূর্ণ। এটি কেবল একবার সদস্য নির্ধারণ করে নেয় ( সমস্ত নির্মাতার মাধ্যমে এটি নিশ্চিত করে নিন ), এবং এটি পরে কখনও না লিখে নিশ্চিত হন।
এটি বলেছে যে এটি করা আপনার ওওপি অনুশীলনগুলিকে বিশৃঙ্খলা করবে না .. এটি কেবল তখনই ব্যবহৃত হয় যখন প্রকারের তথ্য কেবল সহজলভ্য না হয় এবং আপনি আরটিটিআই ব্যবহার করে নিজেকে কোণঠাসা করে দেখেন।
#include <stdio.h>
#include <vector>
using namespace std;
enum AnimalClassTypeTag
{
TypeAnimal=1,
TypeCat=1<<2,TypeBigCat=1<<3,TypeDog=1<<4
} ;
struct Animal
{
int typeTag ;// really AnimalClassTypeTag, but it will complain at the |= if
// at the |='s if not int
Animal() {
typeTag=TypeAnimal; // start just base Animal.
// subclass ctors will |= in other types
}
virtual ~Animal(){}//make it polymorphic too
} ;
struct Cat : public Animal
{
Cat(){
typeTag|=TypeCat; //bitwise OR in the type
}
} ;
struct BigCat : public Cat
{
BigCat(){
typeTag|=TypeBigCat;
}
} ;
struct Dog : public Animal
{
Dog(){
typeTag|=TypeDog;
}
} ;
typedef unsigned long long ULONGLONG;
void dynamicCasts(vector<Animal*> &zoo, ULONGLONG tests)
{
ULONGLONG animals=0,cats=0,bigcats=0,dogs=0;
for( ULONGLONG i = 0 ; i < tests ; i++ )
{
for( Animal* an : zoo )
{
if( dynamic_cast<Dog*>( an ) )
dogs++;
else if( dynamic_cast<BigCat*>( an ) )
bigcats++;
else if( dynamic_cast<Cat*>( an ) )
cats++;
else //if( dynamic_cast<Animal*>( an ) )
animals++;
}
}
printf( "%lld animals, %lld cats, %lld bigcats, %lld dogs\n", animals,cats,bigcats,dogs ) ;
}
//*NOTE: I changed from switch to if/else if chain
void regularSwitch(vector<Animal*> &zoo, ULONGLONG tests)
{
ULONGLONG animals=0,cats=0,bigcats=0,dogs=0;
for( ULONGLONG i = 0 ; i < tests ; i++ )
{
for( Animal* an : zoo )
{
if( an->typeTag & TypeDog )
dogs++;
else if( an->typeTag & TypeBigCat )
bigcats++;
else if( an->typeTag & TypeCat )
cats++;
else
animals++;
}
}
printf( "%lld animals, %lld cats, %lld bigcats, %lld dogs\n", animals,cats,bigcats,dogs ) ;
}
int main(int argc, const char * argv[])
{
vector<Animal*> zoo ;
zoo.push_back( new Animal ) ;
zoo.push_back( new Cat ) ;
zoo.push_back( new BigCat ) ;
zoo.push_back( new Dog ) ;
ULONGLONG tests=50000000;
dynamicCasts( zoo, tests ) ;
regularSwitch( zoo, tests ) ;
}