<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Viele Basisklassen, Zeitverlust?]]></title><description><![CDATA[<p>Grüsse zusammen,</p>
<p>Aus meinem vorherigen Thread, bin ich auf den Visitor gestossen, welcher bei mir aber etwas umständlich umzusetzen ist. Ich habe für mich nun eine einigermasen befriedigende Lösung gefunden.</p>
<p>Ich habe allerdings schon oft gehört, dass Polymorphie ein grosser Zeitverlust auslösen kann. Erst recht, wenn man von mehreren Basisklassen erbt.</p>
<p>Ich denke nicht, dass es bei mir zu irgendwelchen Problemen kommen wird, da andere Bereiche des Codes, wesentlich mehr Zeit verschlingen werden, trotzdem hätte ich gerne gewusst, in welchem Masse sich der Zeitverlust etwa bewegt.</p>
<p>Deshalb mal ein wenig Code:</p>
<pre><code class="language-cpp">// Grundstruktur

template&lt;typename T&gt;
class CVisitorMethod
{
protected:
    CVisitorMethod() { };
    virtual ~CVisitorMethod() { };

public:
    virtual void visit(T&amp;) { };
};

class CBasicVisitor
{
public:
    template&lt;typename T&gt;
    void visit(T&amp; rT)
    {
        CVisitorMethod&lt;T&gt;* pVM = dynamic_cast&lt;CVisitorMethod&lt;T&gt;*&gt;(this);

        if(pVM)
        { pVM-&gt;visit(rT); }
        else
        { undefined_visit(); }
    }

    virtual void undefined_visit() = 0;
};

// Eine Basisklasse

class B
{
public:
    virtual void apply_visitor(CBasicVisitor&amp; rVisitor) = 0;
};

// Eine paar Klassen

class X : public B
{
public:
    virtual void apply_visitor(CBasicVisitor&amp; rVisitor) { rVisitor.visit(*this); };
};

class Y : public B
{
public:
    virtual void apply_visitor(CBasicVisitor&amp; rVisitor) { rVisitor.visit(*this); };
};

// Ein paar Visitoren
class CNormalVisitor : public CBasicVisitor, public CVisitorMethod&lt;X&gt;, public CVisitorMethod&lt;Y&gt;
{
public:
    virtual void visit(X&amp;) { std::cout &lt;&lt; &quot;X&quot; &lt;&lt; std::endl; };
    virtual void visit(Y&amp;) { std::cout &lt;&lt; &quot;Y&quot; &lt;&lt; std::endl; };

    virtual void undefined_visit() { std::cout &lt;&lt; &quot;Undefined visit&quot; &lt;&lt; std::endl; };
};

template&lt;typename T&gt;
class CIsType : public CBasicVisitor, public CVisitorMethod&lt;T&gt;
{
private:
    bool m_bIsTrue;

public:
    CIsType() : m_bIsTrue(false) { };

    virtual void visit(T&amp;) { m_bIsTrue = true; };
    virtual void undefined_visit() { m_bIsTrue = false; };

    bool is_true() const { return m_bIsTrue; };
};

int main()
{
    B* pX = new X;
    B* pY = new Y;

    CNormalVisitor NormalVisitor;

    pX-&gt;apply_visitor(NormalVisitor);
    pY-&gt;apply_visitor(NormalVisitor);

    CIsType&lt;Y&gt; IsTypeY;

    pX-&gt;apply_visitor(IsTypeY);
    std::cout &lt;&lt; (IsTypeY.is_true() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; std::endl;

    pY-&gt;apply_visitor(IsTypeY);
    std::cout &lt;&lt; (IsTypeY.is_true() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; std::endl;

    delete pX;
    delete pY;

    std::cin.clear();
    std::cin.sync();
    std::cin.get();
}
</code></pre>
<p>Es geht halt dann vor allem darum, wenn man sehr viele CVisitorMethod Basisklassen hat. Wie stark könnte ein Programm deswegen ausgebremst werden? Ist das ein normaler dynamic_cast, wie auch bei normaler einzel Basisklassen Polymorphie oder kostet er wirklich mehr Zeit? Ab wievielen Basisklassen gibt es &quot;Probleme&quot;?</p>
<p>Danke für die Antwort!</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/215511/viele-basisklassen-zeitverlust</link><generator>RSS for Node</generator><lastBuildDate>Mon, 12 Oct 2026 06:54:51 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/215511.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 12 Jun 2008 00:14:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 00:14:30 GMT]]></title><description><![CDATA[<p>Grüsse zusammen,</p>
<p>Aus meinem vorherigen Thread, bin ich auf den Visitor gestossen, welcher bei mir aber etwas umständlich umzusetzen ist. Ich habe für mich nun eine einigermasen befriedigende Lösung gefunden.</p>
<p>Ich habe allerdings schon oft gehört, dass Polymorphie ein grosser Zeitverlust auslösen kann. Erst recht, wenn man von mehreren Basisklassen erbt.</p>
<p>Ich denke nicht, dass es bei mir zu irgendwelchen Problemen kommen wird, da andere Bereiche des Codes, wesentlich mehr Zeit verschlingen werden, trotzdem hätte ich gerne gewusst, in welchem Masse sich der Zeitverlust etwa bewegt.</p>
<p>Deshalb mal ein wenig Code:</p>
<pre><code class="language-cpp">// Grundstruktur

template&lt;typename T&gt;
class CVisitorMethod
{
protected:
    CVisitorMethod() { };
    virtual ~CVisitorMethod() { };

public:
    virtual void visit(T&amp;) { };
};

class CBasicVisitor
{
public:
    template&lt;typename T&gt;
    void visit(T&amp; rT)
    {
        CVisitorMethod&lt;T&gt;* pVM = dynamic_cast&lt;CVisitorMethod&lt;T&gt;*&gt;(this);

        if(pVM)
        { pVM-&gt;visit(rT); }
        else
        { undefined_visit(); }
    }

    virtual void undefined_visit() = 0;
};

// Eine Basisklasse

class B
{
public:
    virtual void apply_visitor(CBasicVisitor&amp; rVisitor) = 0;
};

// Eine paar Klassen

class X : public B
{
public:
    virtual void apply_visitor(CBasicVisitor&amp; rVisitor) { rVisitor.visit(*this); };
};

class Y : public B
{
public:
    virtual void apply_visitor(CBasicVisitor&amp; rVisitor) { rVisitor.visit(*this); };
};

// Ein paar Visitoren
class CNormalVisitor : public CBasicVisitor, public CVisitorMethod&lt;X&gt;, public CVisitorMethod&lt;Y&gt;
{
public:
    virtual void visit(X&amp;) { std::cout &lt;&lt; &quot;X&quot; &lt;&lt; std::endl; };
    virtual void visit(Y&amp;) { std::cout &lt;&lt; &quot;Y&quot; &lt;&lt; std::endl; };

    virtual void undefined_visit() { std::cout &lt;&lt; &quot;Undefined visit&quot; &lt;&lt; std::endl; };
};

template&lt;typename T&gt;
class CIsType : public CBasicVisitor, public CVisitorMethod&lt;T&gt;
{
private:
    bool m_bIsTrue;

public:
    CIsType() : m_bIsTrue(false) { };

    virtual void visit(T&amp;) { m_bIsTrue = true; };
    virtual void undefined_visit() { m_bIsTrue = false; };

    bool is_true() const { return m_bIsTrue; };
};

int main()
{
    B* pX = new X;
    B* pY = new Y;

    CNormalVisitor NormalVisitor;

    pX-&gt;apply_visitor(NormalVisitor);
    pY-&gt;apply_visitor(NormalVisitor);

    CIsType&lt;Y&gt; IsTypeY;

    pX-&gt;apply_visitor(IsTypeY);
    std::cout &lt;&lt; (IsTypeY.is_true() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; std::endl;

    pY-&gt;apply_visitor(IsTypeY);
    std::cout &lt;&lt; (IsTypeY.is_true() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; std::endl;

    delete pX;
    delete pY;

    std::cin.clear();
    std::cin.sync();
    std::cin.get();
}
</code></pre>
<p>Es geht halt dann vor allem darum, wenn man sehr viele CVisitorMethod Basisklassen hat. Wie stark könnte ein Programm deswegen ausgebremst werden? Ist das ein normaler dynamic_cast, wie auch bei normaler einzel Basisklassen Polymorphie oder kostet er wirklich mehr Zeit? Ab wievielen Basisklassen gibt es &quot;Probleme&quot;?</p>
<p>Danke für die Antwort!</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527363</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527363</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 12 Jun 2008 00:14:30 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 04:58:03 GMT]]></title><description><![CDATA[<p>naja also grundsätzlich gilt:</p>
<p>virtual braucht etwas zeit...</p>
<p>der compiler erstellt da vTables in der die addressen von den klassen gespeichert sind und muss sich immer erst die adressen aus der tabelle holen statt direkt darauf zu zugreifen<br />
<a href="http://tutorial.schornboeck.net/virtual_kosten.htm" rel="nofollow">Was kostet 'virtual'?</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527371</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527371</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Thu, 12 Jun 2008 04:58:03 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 05:59:40 GMT]]></title><description><![CDATA[<p>kosten sind relativ. wie du selbst bereits bemerkt hast, brauchen andere ecken deines programms sowieso &quot;ewig&quot; im vergleich zu dem, was ein lookup in der vtable kostet. wenn man auf polymorphie verzichtet und sich als ersatz ein paar kontrollstrukturen einzieht, wirds eh auf dasselbe hinauslaufen.</p>
<p>noch toller wirds mit so brutalen geschichten wie file access oder remote calls. da kannst du tausende virtual methoden einbauen, im vergleich zu den wirklich teuren operationen fallen die dann kaum noch ins gewicht.</p>
<p>so als grobe faustformel vielleicht: wenn man irgendwo noch 2 ms mehr speed rauskitzeln muss, dann sollte man sich vielleicht auch mal die virtual methoden angucken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527380</guid><dc:creator><![CDATA[virtualizer]]></dc:creator><pubDate>Thu, 12 Jun 2008 05:59:40 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 06:01:24 GMT]]></title><description><![CDATA[<p>wobei zeitangaben wahrscheinlich sogar nichts bringen. eher wenn man taktzyklen sparen muss, lohnen sich solche mikrooptimierungen. wenn der code also auf nem toaster rennt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527381</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527381</guid><dc:creator><![CDATA[virtualizer]]></dc:creator><pubDate>Thu, 12 Jun 2008 06:01:24 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 08:31:20 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Ich habe allerdings schon oft gehört, dass Polymorphie ein grosser Zeitverlust auslösen kann.</p>
</blockquote>
<p>Leute, die sowas erzählen, gehören doch weggesperrt.</p>
<p>Der Visitor in Deinem Code erfüllt doch einen gewissen Zweck. Wenn Du den ohne Visitor schreiben würdest, müsstest Du doch auch irgendwelche Tests ausführen – halt nur manuell. Das wird dadurch garantiert nicht schneller.</p>
<p>Die Frage ist hingegen, ob der Visitor hier wirklich angebracht ist. Visitor ist von allen Entwurfsmustern wahrscheinlich das komplexeste, am aufwendigsten zu programmierende und zu erweiternde. IMHO sollte man lieber versuchen, um den Double Dispatch herumzukommen, indem man die Semantik ändern oder zweidimensionale Lookup-Tables verwendet (falls das in Deinem Fall möglich ist).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527460</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Thu, 12 Jun 2008 08:31:20 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 11:40:50 GMT]]></title><description><![CDATA[<p>Erstmal danke für die Antworten.</p>
<p>Mir ist schon klar, dass virtual mehr Zeit braucht, dass es allerdings auch eher Mikro, wenn nicht gar sogar Nanooptimierungen sind. Mir ging es mehr darum, ob es einen Unterschied macht, wenn man viele Basisklassen hat im Gegensatz zu wenigen. Also steigt dieser minimale Zeitverlust proportional zu den Anzahl Basisklassen, bzw. virtueller Methoden?</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/5021">@Konrad</a> Rudolph,<br />
Ja, der Visitor erfüllt einen gewissen Zweck. Und mit den meisten anderen Lösungen bräuchte ich wohl so oder so ca. 4-16 <code>If</code> -Abfragen und wohl auch noch Schleifen.</p>
<p>Und der Visitor ist zum Beispiel bei <code>CIsType</code> nicht angebracht. Da würde theoretisch ein <code>dynamic_cast</code> reichen, aber das war ja nur ein Beispiel.<br />
Beim tatsächlichen Code ist es so, dass ich eine extrem allgemeine Visitor Schnittstelle benötige, bzw. möchte.<br />
Das wichtigste an diesem Visitor ist, dass die Basis ( <code>CBasicVisitor</code> ) keine Ahnung haben soll, was für Klassen von <code>B</code> abgeleitet wurden, aber trotzdem darauf reagieren können soll.</p>
<p>Übrigens, noch eine zusätzliche Frage: Ist die Zeit, welche für einen <code>dynamic_cast</code> verwendet wird gleich der Zeit, welche für einen Aufruf einer virtuellen Funktion benötigt wird?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527675</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527675</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 12 Jun 2008 11:40:50 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 12:24:42 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Übrigens, noch eine zusätzliche Frage: Ist die Zeit, welche für einen <code>dynamic_cast</code> verwendet wird gleich der Zeit, welche für einen Aufruf einer virtuellen Funktion benötigt wird?</p>
</blockquote>
<p>Nein. Ein virtueller Aufruf ist im Normalfall einfach eine Addition zweier Zeiger plus ein Call. Ein 'dynamic_cast' hingegen führt eine Typenüberprüfung durch, welche sehr unterschiedlich implementiert werden kann; selbst in der effizientesten Implementierung kann es aber passieren, dass mehrere Zeigervergleiche ausgeführt werden müssen. Allerdings könnte es sein, dass der 'dynamic_cast' zumindest bei einer flachen Vererbungshierarchie (d.h. nur eine Basisklasse, welche ihrerseits keine weiteren Basisklassen besitzt) in etwa gleichschnell ist wie ein virtueller Methodenaufruf.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527718</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527718</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Thu, 12 Jun 2008 12:24:42 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 15:45:54 GMT]]></title><description><![CDATA[<p>Herzlichen Dank für die Info.<br />
Wo kann man eigentlich solche Dinge nachlesen? Gibt es irgendein Buch, welches den C++ Standard wirklich gründlich und trocken erläutert? Bzw. am besten eigentlich ein Nachschlagewerk.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527902</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527902</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 12 Jun 2008 15:45:54 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 15:49:15 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Wo kann man eigentlich solche Dinge nachlesen? Gibt es irgendein Buch, welches den C++ Standard wirklich gründlich und trocken erläutert? Bzw. am besten eigentlich ein Nachschlagewerk.</p>
</blockquote>
<p>Hmm. Also ganz praktisch ist da „Effective C++“ von Meyers. Ultimatives Nachschlagewerk ist natürlich der Standard selbst, der aber ein nettes Sümmchen kostet (wobei im Netz irgendwo eine PDF-Version rumfliegt …).</p>
<p>Ich muss aber ehrlich zugeben, dass ich gar nicht weiß, inwiefern diese Implementierungsdetails im Standard so genau erklärt sind, soweit ich weiß, steht es dem Implementierer frei, wie er diesen Typenvergleich realisiert. Ein wenig Erfahrung mit Compilerbau verrät einem aber, wie sowas effizient geht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527905</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527905</guid><dc:creator><![CDATA[Konrad Rudolph]]></dc:creator><pubDate>Thu, 12 Jun 2008 15:49:15 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Thu, 12 Jun 2008 18:41:37 GMT]]></title><description><![CDATA[<p>Na, im Standard stehen natürlich nur Vorschriften zum Verhalten drin. Wie das Verhalten implementiert ist, steht da nicht drin. Ist auch nicht Sinn des Standards. Z.B. steht bei Vectoren drin, das die Daten darin sequenziell abgelegt werden sollen. Wie dieses sequenzielle implementiert ist, steht jedoch offen. Es ist lediglich für den Implementierer meistens offensichtlich, das es bei einem Array enden wird. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>In Effektiv C++ von Scott Meyers werden solche Dinge angesprochen. Aber auch dort steht dann so sinngemäß drin &quot;Die meisten Compiler die ich getestet habe, implementieren es so und so.&quot;. Weil man es einfach nicht für jeden Compiler und Standardlib dieses Planeten sagen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1527991</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1527991</guid><dc:creator><![CDATA[HansiHinterseher]]></dc:creator><pubDate>Thu, 12 Jun 2008 18:41:37 GMT</pubDate></item><item><title><![CDATA[Reply to Viele Basisklassen, Zeitverlust? on Fri, 13 Jun 2008 07:33:39 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>also in der &quot;exceptional&quot;-Serie von Herb Sutter stehen tw. auch so Sachen drin und etwas ausführlicher habe ich dazu noch in <a href="http://www.amazon.de/Imperfect-C%2B%2B-Practical-Solutions-Programming/dp/0321228774/" rel="nofollow">&quot;Imperfect C++&quot; von Matthew Wilson</a> gelesen.<br />
Da geht's oftmals aber eher um &quot;C++-Std&quot;-Themen (wie (gut) ist welches Feature vom Compiler umgesetzt ?). Einige ganz nette Informationen konkret zum Thema &quot;Optimierung&quot; gab es in <a href="http://www.agner.org/optimize/optimizing_cpp.pdf" rel="nofollow">einem Skript</a>, das hier im Forum mal erwähnt wurde (überhaupt sieht dessen Homepage ganz interessant aus: <a href="http://www.agner.org/optimize/" rel="nofollow">http://www.agner.org/optimize/</a>).</p>
<p>Wo man das aber mal &quot;gesammelt&quot; überblicken kann, weiß ich auch nicht.</p>
<p>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1528208</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1528208</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Fri, 13 Jun 2008 07:33:39 GMT</pubDate></item></channel></rss>