На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: JoeUser, Qraizer, Hsilgos
Страницы: (4) « Первая ... 2 3 [4]  все  ( Перейти к последнему сообщению )  
> насколько тормозной dynamic_cast?
    Ну собственно я про это и написал. Как ещё проверить находится ли один узел в поддереве другого. Единственный эффективный способ спуститься по дереву иерархии от наследника к предку. Мы либо наткнёмся на переданный класс и выполним приведение, либо дойдём до конца иерархии, так и не встретив переданного класса, и вернём ноль, в знак того, что приведение невозможно. Это при одиночном наследовании.
    Можно развернуть цикл спуска в точке приведения, проверка будет быстрее. Кроме того, так можно прервать проверки до достижения самого корневого класса (переданный в dynamic_cast указатель сам может быть производным, и его базовые классы проверять незачем).
    При множественном наследовании при скольжении по дереву возможно несколько продолжений. Однако только одно может вести к классу передаваемого указателя. В этом случае развёртывание цикла даёт даже больший эффект, так как не приходится перебирать варианты продолжений.
    Всё написанное выше это всего лишь моё мнение, возможно ошибочное.
      По-моему, вы упускаете из виду такой вариант, или я вас не так понял:
      ExpandedWrap disabled
        class IInterface1 { /* ... */ };
        class IInterface2 { /* ... */ };
         
        class MyClass: public IInterface1, public IInterface2 { /* ... */ };
         
        void foo(IInterface1* pInt1)
        {
          /* ... */
         
          IInterface2 pInt2 = dynamic_cast<IInterface2*>(pInt1);
         
          if (pInt2 != 0)
          /* ... */
        }
      Перекрёстное приведение – часто встречающаяся фича. Класс может реализовывать несколько интерфейсов, и нередко встаёт задача проверки того, поддерживает ли он тот или иной интерфейс, и делается это перекрёстным приведением. Причём тут ещё простой пример.

      P.S. Говоря об обходе графа, я не преувеличивал.
      Сообщение отредактировано: Qraizer -
      Одни с годами умнеют, другие становятся старше.
        Цитата Qraizer @
        Перекрёстное приведение – часто встречающаяся фича.
        Вот тут согласен. В этом случае выглядит практически нереальным во время компиляции угадать цепочку приведения. Значит остаётся только бродить по графу разыскивая нужный маршрут. И это достаточно медленный процесс, особенно в случае неудачи.
        Всё написанное выше это всего лишь моё мнение, возможно ошибочное.
          Цитата Qraizer @
          По-моему, вы упускаете из виду такой вариант, или я вас не так понял:

          Я лишь хотел уточнить, что несмотря на обобщенное название темы, автора (в первую очередь) интересует конкретная простая ситуация, когда за номинальным
          базовым типом ObjectBase* скрывается реальный объект типа XObject*, к которому и нужно выполнить dynamic_cast (см.#1 и пояснение в #8). Поэтому прежде чем разглагольствовать на общие темы (на 4 страницах), следовало бы пояснить, что в данном конкретном случае dynamic_cast выполняется максимально быстро (за одно сравнение typeid реального типа с требуемым).
            Цитата leo @
            Я лишь хотел уточнить, что несмотря на обобщенное название темы, автора (в первую очередь) интересует конкретная простая ситуация, когда за номинальным
            базовым типом ObjectBase* скрывается реальный объект типа XObject*, к которому и нужно выполнить dynamic_cast (см.#1

            Да, действительно, меня интересовала конкретика. Но ради понимания общего механизма, на будущее, все остальные объяснения, тоже были интересны.
            Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
              Цитата leo @
              за одно сравнение typeid реального типа с требуемым
              Сравнений может быть и больше. Приведение нормально выполняется ещё и в случаях, когда реальный тип оказывается наследником требуемого. А это можно выяснить только пробежав по всей цепочке наследования от реального типа к требуемому.
              Всё написанное выше это всего лишь моё мнение, возможно ошибочное.
                Цитата amk @
                Приведение нормально выполняется ещё и в случаях, когда реальный тип оказывается наследником требуемого.

                Это уже обобщение. Я говорю о конкретном случае (см.#1 и #8), когда dynamic_cust выполняется не "от балды", а только после предварительной проверки типа объекта по уникальному идентификатору типа Category (или по тому же tipeid). Если автор обобщит задачу и будет присваивать одно значение Category двум и более наследуемым классам, то да - проверка будет выполняться по цепочке "от реального типа к требуемому". А пока у него реальный тип = требуемому, проверка при dynamic_cust выполняется за одно сравнение.
                  Цитата leo @
                  Если автор обобщит задачу и будет присваивать одно значение Category двум и более наследуемым классам, то да - проверка будет выполняться по цепочке "от реального типа к требуемому". А пока у него реальный тип = требуемому,
                  проверка при dynamic_cust выполняется за одно сравнение.

                  У меня category выставляется полуавтоматически. Собственно я завёл её как раз ради такой или подобной идентификации. Например, чтобы из списка разных объектов, быстро выбрать объекты нужных категорий.
                  Но в некоторых местах, получилось весело и неоднозначно.
                  У меня есть ромбовидная иерархия...

                  ExpandedWrap disabled
                    ]
                    class ObjectBase abstract
                    {}
                     
                    class XObject:
                    public virtual ObjectBase
                    {};
                     
                    class YObject:
                    public virtual ObjectBase
                    {};
                     
                     
                    class XYObject final:
                    public XObject,
                    public YObject
                    {
                    };


                  Причём объекты нужны и могут быть типов XObject, YObject или XYobject.

                  В первом сообщении, я спрашивал лишь про один фрагмент. Но оно действительно для всех классов.
                  Несколько функций работают только с XObject или YObject.
                  Понятно и допустимо, что они будут работать с XYObject.
                  Но моя первоначальная функция приведения, точнее проверки категорий, ломались на таком. Пришлось делать идентификаторы из битовых флагов.

                  ExpandedWrap disabled
                    enum class ObjectCategory
                    {
                    XObject = 0x0011,
                    YObject = 0x0012,
                    XYObject = 0x0013
                    };


                  Ну и проверка, соответственно уже проверяла маску, а не полное равенство.
                  Ох и морока же. Была мысль заюзать std::bitset или switch. Но остановился на битовых флагах.

                  И да в предыдущем варианте тестирования, кроме приведение типа объекта, к его реальному типу, делалось соответственно приведение к одному из базовых типов. Если реальный объект XYObject, а нужен только XObject, указатель же вообще ObjectBase...
                  Но даже в этом случае, всё отрабатывало быстро и чётко.

                  Как я понимаю, сначала dynamic_cast смотрел VMT и обнаружив там XYObject, спускался вниз по иерархии, проверяя либо XObject либо YObject.
                  Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
                    Дружище, на сколько я понял, был главный вопрос этот:
                    Цитата Eric-S @
                    но насколько это плохо?
                    Можно "копья ломать" еще стопицот страниц. Домыслы, догадки. Но решение в каких-то числах, пусть в шкальных оценках, ИМХО, тебе дадут тесты. Сделай пару-тройку синтетических примеров с разветвленным множественным наследованием, замерь на таймере высокого разрешения - и ты получишь, как минимум, порядок в разности скоростей. Чесслово, рассуждений выше для тестов - выше крыши. А вот численный результат, уверен, был бы любопытен всем :)
                    Мои программные ништякиhttp://majestio.info
                      Цитата JoeUser @
                      Но решение в каких-то числах, пусть в шкальных оценках, ИМХО, тебе дадут тесты.

                      Пытался замерять такты, через clock().
                      там значения плавали, для одного и того же кода. При этом два диапазона значений, для двух разных кодов, были довольно близкими. Я не смог однозначно сказать, что какой-то код быстрее. Субъективно же чуточку ускорилось.
                      Следовало сразу мерить профайлером, в более суровых и чистых условиях, а теперь поздняк метаться. На данный момент у меня нет действющих dynamic_cast.
                      Человек должен делать то, что может сделать только он, всё остальное должна делать машина!
                        Цитата Eric-S @
                        Я не смог однозначно сказать, что какой-то код быстрее. Субъективно же чуточку ускорилось.

                        На большлом компе проверял? проверь на железке с памятью 2М, и скоростью
                        машины времен начала 90-х, хотя бы.Либо каждый замен времени умножай на 100 или 1000,
                        и сравни есть ли разница, это че совсем точно,но лучше чем никак.
                          Цитата settler @
                          Либо каждый замен времени умножай на 100 или 1000,
                          Лучше повторять тест. Подобрать такое количество повторов, чтобы вместе они занимали 1-10 секунд. Тогда по крайней мере паре-тройке цифр в результате можно будет доверять.

                          Цитата Eric-S @
                          там значения плавали, для одного и того же кода. При этом два диапазона значений, для двух разных кодов, были довольно близкими. Я не смог однозначно сказать, что какой-то код быстрее.
                          Значит можно считать, что притормаживание несущественно. В любом случае основное время у тебя занимает обработка после проверки, и на фоне этого времени небольшое притормаживание dynamic_cast будет незаметно.
                          Всё написанное выше это всего лишь моё мнение, возможно ошибочное.
                          1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script Execution time: 0,1203 ]   [ 15 queries used ]   [ Generated: 18.07.18, 14:41 GMT ]