글쎄, 프로파일 러는 절대 거짓말하지 않습니다.
나는 크게 변하지 않는 18-20 유형의 꽤 안정적인 계층 구조를 가지고 있기 때문에 간단한 열거 형 멤버를 사용 하여 트릭을 수행하고 RTTI의 "높은"비용을 피할 수 있을지 궁금했습니다 . RTTI가 실제로 if
소개 하는 내용 보다 비싸면 회의적이었습니다 . 소년 아 소년 아
RTTI 는 비싸고 동등한 명령문 보다 훨씬 비싸 if
거나 switch
C ++의 기본 변수에 대해서는 단순 합니다. S. 로트의 대답은 완전히 정확하지 그래서이 있다 RTTI에 대한 추가 비용, 그건 하지 단지로 인해 성기를 갖는 if
문 믹스를. RTTI가 매우 비싸기 때문입니다.
이 테스트는 Apple LLVM 5.0 컴파일러에서 스톡 최적화가 켜진 상태에서 수행되었습니다 (기본 릴리스 모드 설정).
따라서 2 가지 기능이 있습니다. 각 기능은 1) RTTI 또는 2) 간단한 스위치를 통해 객체의 구체적인 유형을 나타냅니다. 그렇게 50,000,000 번입니다. 더 이상 고민하지 않고 50,000,000 회의 상대 런타임을 제시합니다.
맞습니다 . 런타임의 94 % 가 dynamicCasts
소요되었습니다 . 그동안 블록 만했다 3.3 %를 .regularSwitch
긴 이야기를 짧게 : 당신이에 후크 할 수있는 에너지를 줄 수있는 경우에 enum
나는 아래처럼 'D 타입은 RTTI를 할 필요가 있다면, 아마, 그것을 권하고 싶습니다 그리고 성능이 중요합니다. 멤버를 한 번만 설정 하면 ( 모든 생성자 를 통해 가져와야 함 ) 나중에 작성하지 마십시오.
즉, 이렇게하면 OOP 관행을 망칠 수 없습니다. 형식 정보를 사용할 수없고 RTTI를 사용하는 경우에만 사용해야합니다.
#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 ) ;
}