Re: По мотивам RTTI
От: Павел Кузнецов  
Дата: 25.03.02 12:50
Оценка: 4 (1)
M>что быстрее: switch (p->GetType()) или последовательный if (MessageClick* p2 = dynamic_cast<MessageClick*>(p)){} else if...
M>Кто-нибудь знает насколько быстро работает dynamic_cast по сравнению с вызовом виртуальной функции?

Вообще, это некорректный вопрос. Для разных компиляторов значения будут разными. В принципе, можно ожидать, что switch будет быстрее. Например, для MSVC++7.0, если вызов функции принять за единицу, числа примерно такие:

virtual function call: 1.37487
dynamic_cast<Derived*>(base): 13.2874
dynamic_cast<MultipleDerived*>(base1): 15.1835
dynamic_cast<MultipleDerived*>(base2): 22.739
dynamic_cast<VirtualDerived*>(vbase): 13.2515
dynamic_cast<MultipleVirtualDerived*>(vbase): 35.6703

Однако, следует заметить, что, за редким исключением, вместо поиска лучшего typeid следует пересмотреть дизайн приложения. Для большинства реальных приложений скорость выполнения инструкции dynamic_cast вполне адекватна. Кроме того, "самопальные" решения для RTTI в большинстве случаев не могут учесть многих тонкостей и, как следствие, обычно ведут к снижению надежности и/или ухудшению общего дизайна приложения.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
По мотивам RTTI
От: Mishka Норвегия  
Дата: 25.03.02 10:28
Оценка:
Имею класс:
class IMessage
{
public:
      virtual int GetType() const = 0;
};

class MessageClick
{
public:
      virtual int GetType() const {return MT_CLICK;}
};


А потом в коде нужно, имея IMessage, узнать тип сообщения и привести его к этому типу. Так вот встал вопрос:
что быстрее: switch (p->GetType()) или последовательный if (MessageClick* p2 = dynamic_cast<MessageClick*>(p)){} else if...
Кто-нибудь знает насколько быстро работает dynamic_cast по сравнению с вызовом виртуальной функции?
Re[2]: По мотивам RTTI
От: Dima2  
Дата: 25.03.02 12:56
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Для большинства реальных приложений скорость выполнения инструкции dynamic_cast вполне адекватна.


Да вполне. Просто хочу добавить что тут зависит от того что к чему приводиться производный тип к базовому или наоборот. Если производный к базовому, то dynamic_cast просто возвращает указатель на производный класс, а вот если наоборот, то тут идет сравнение RTTI по полной программе и скорость такого приведения значительно снижается.
Re: По мотивам RTTI
От: OlegN  
Дата: 25.03.02 16:58
Оценка:
Здравствуйте Mishka, Вы писали:

M>Имею класс:

M>
M>class IMessage
M>{
M>public:
M>      virtual int GetType() const = 0;
M>};

M>class MessageClick
M>{
M>public:
M>      virtual int GetType() const {return MT_CLICK;}
M>};
M>


M>А потом в коде нужно, имея IMessage, узнать тип сообщения и привести его к этому типу. Так вот встал вопрос:

M>что быстрее: switch (p->GetType()) или последовательный if (MessageClick* p2 = dynamic_cast<MessageClick*>(p)){} else if...
M>Кто-нибудь знает насколько быстро работает dynamic_cast по сравнению с вызовом виртуальной функции?

Я бы спрашивал насколько медленно. Механизм виртуальных функции работает быстрее.
Но я бы на этом не останавливался. Ударьте полиморфизмом по switch в клиентском классе:

void OnMessage( const IMessage& Msg)
{
// обработка по умолчанию — аналог default в switch
// обычно ничего не делается
}

void OnMessage( const MessageClick& ClickMsg)
{
// специфичная обработка
}
Re[2]: По мотивам RTTI
От: Павел Кузнецов  
Дата: 26.03.02 08:12
Оценка:
ON>(...) Ударьте полиморфизмом по switch в клиентском классе:
ON>void OnMessage( const IMessage& Msg) ...
ON>void OnMessage( const MessageClick& ClickMsg) ...

<pedantic>
В своем сообщении маэстро, говоря о полиморфизме, привел пример перегрузки функций.
</pedantic>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: По мотивам RTTI
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.03.02 08:20
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ON>>(...) Ударьте полиморфизмом по switch в клиентском классе:

ON>>void OnMessage( const IMessage& Msg) ...
ON>>void OnMessage( const MessageClick& ClickMsg) ...

ПК><pedantic>

ПК>В своем сообщении маэстро, говоря о полиморфизме, привел пример перегрузки функций.
ПК></pedantic>
И правильно сделал. Сие есть частный случай полиморфизма. А то, что в школе учат, что полиморфизм суть наличие ключевого слова виртуал в языке — так это неправда. Это они от незнания.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: По мотивам RTTI
От: Павел Кузнецов  
Дата: 26.03.02 08:50
Оценка:
ПК>>В своем сообщении маэстро, говоря о полиморфизме, привел пример перегрузки функций.
S>И правильно сделал. Сие есть частный случай полиморфизма. А то, что в школе учат, что полиморфизм суть наличие ключевого слова виртуал в языке — так это неправда. Это они от незнания.

Вообще говоря, конечно, перегрузка является разновидностью полиморфизма. Однако, в объектно-ориентированном программировании вообще, и в C++ в частности, для избежания неоднозначности, говоря о статическом полиморфизме принято указывать это явно; просто полиморфизм принято ассоциировать с динамическим связыванием. Более того, в стандарте языка С++ вводится понятие полиморфных объектов (объекты классов, имеющих виртуальные функции). Поэтому, в контексте C++, IMHO, использование термина полиморфизм для обозначения перегрузки функций вносит ненужную путаницу.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: По мотивам RTTI
От: Mishka Норвегия  
Дата: 26.03.02 09:37
Оценка:
Здравствуйте OlegN, Вы писали:
ON>Но я бы на этом не останавливался. Ударьте полиморфизмом по switch в клиентском классе:

Я б тоже не останавливался, да нельзя. Поскольку количество подклассов IMessage заранее не известно и события отправляются в абстрактный класс с одним методом SendMessage(IMessage*), который потом кто-то перегружает.
Re[3]: По мотивам RTTI
От: Anton V. Kolotaev  
Дата: 26.03.02 09:43
Оценка:
Здравствуйте Mishka, Вы писали:

M>Поскольку количество подклассов IMessage заранее не известно и события отправляются в абстрактный класс с одним методом SendMessage(IMessage*), который потом кто-то перегружает.


А не пахнет ли здесь паттерном посетитель?
Re[4]: По мотивам RTTI
От: Mishka Норвегия  
Дата: 26.03.02 10:06
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Здравствуйте Mishka, Вы писали:


M>>Поскольку количество подклассов IMessage заранее не известно и события отправляются в абстрактный класс с одним методом SendMessage(IMessage*), который потом кто-то перегружает.


AVK>А не пахнет ли здесь паттерном посетитель?


По моему нет. Это больше на Command похоже.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.