<?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[Optimierung, Templates]]></title><description><![CDATA[<p>Hi,</p>
<p>Ist hier davon auszugehen, dass der std::string nicht wirklich erstellt werden muss? (Soll heißen der Text der hinter p steht muss nicht kopiert werden.)</p>
<pre><code class="language-cpp">template&lt;class T = std::string::const_iterator&gt;
void foo(T begin, T end)
{
  // ..
}
void foo(const char* p)
{
  const std::string s(p);
  foo(s.begin(), s.end());
}
</code></pre>
<p>Macht so ein Template überhaupt Sinn, wenn klar ist, dass {T i; typeid(*i) == typeid(char)} gelten muss? Oder macht ihr da gleich etwas mit const char* und erwartet einfach, dass der Nutzer einen C-String übergibt und nicht darauf kommt, z.B. einen std::vector&lt;char&gt; ohne Nullterminierung zu nehmen und einfach &amp;v[0] zu übergeben?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/290442/optimierung-templates</link><generator>RSS for Node</generator><lastBuildDate>Tue, 18 Aug 2026 12:35:05 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/290442.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 26 Jul 2011 16:58:14 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 16:58:14 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>Ist hier davon auszugehen, dass der std::string nicht wirklich erstellt werden muss? (Soll heißen der Text der hinter p steht muss nicht kopiert werden.)</p>
<pre><code class="language-cpp">template&lt;class T = std::string::const_iterator&gt;
void foo(T begin, T end)
{
  // ..
}
void foo(const char* p)
{
  const std::string s(p);
  foo(s.begin(), s.end());
}
</code></pre>
<p>Macht so ein Template überhaupt Sinn, wenn klar ist, dass {T i; typeid(*i) == typeid(char)} gelten muss? Oder macht ihr da gleich etwas mit const char* und erwartet einfach, dass der Nutzer einen C-String übergibt und nicht darauf kommt, z.B. einen std::vector&lt;char&gt; ohne Nullterminierung zu nehmen und einfach &amp;v[0] zu übergeben?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098060</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098060</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 16:58:14 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:02:52 GMT]]></title><description><![CDATA[<p>Der Text hinter <code>p</code> wird garantiert in den <code>std::string</code> kopiert. Zumindest kann ich mir keine COW-Implementierung vorstellen, die automatisch feststellt, falls sich ein Buchstabe des ursprünglichen <code>char</code> -Arrays ändert.</p>
<p>Aber wieso rufst du <code>foo()</code> nicht direkt auf dem <code>char</code> -Array auf, wenn die Funktion schon eine generische Iterator-Schnittstelle anbietet?</p>
<p>Zudem dürfen Funktionstemplates keine Default-Templateparameter haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098063</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098063</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:02:52 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:11:05 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Zudem dürfen Funktionstemplates keine Default-Templateparameter haben.</p>
</blockquote>
<p>aber klassen templates?<br />
oder muss da auch mindestens ein template parameter nicht default sein?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098072</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098072</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:11:05 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:16:24 GMT]]></title><description><![CDATA[<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>aber klassen templates?</p>
</blockquote>
<p>Ja, hier ganz normal. Es können auch alle Templateparameter mit Defaultwerten belegt sein, das führt dann zu Instanziierungen wie</p>
<pre><code class="language-cpp">boost::pool&lt;&gt; p(...);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2098078</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098078</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:16:24 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:16:25 GMT]]></title><description><![CDATA[<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>Nexus schrieb:</p>
<blockquote>
<p>Zudem dürfen Funktionstemplates keine Default-Templateparameter haben.</p>
</blockquote>
<p>aber klassen templates?<br />
oder muss da auch mindestens ein template parameter nicht default sein?!</p>
</blockquote>
<p>Klassentemplates dürfen vollständig oder auch teilweise Defaultparameter haben.</p>
<p>edit: Zu langsam</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098081</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098081</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:16:25 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:24:48 GMT]]></title><description><![CDATA[<p>Wenn du Optimieren willst, dann umgekehrt:<br />
C-String zu <code>std::string</code> = teuer<br />
<code>std::string</code> zu C-String = billig</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098089</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098089</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:24:48 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:30:57 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Aber wieso rufst du <code>foo()</code> nicht direkt auf dem <code>char</code> -Array auf, wenn die Funktion schon eine generische Iterator-Schnittstelle anbietet?</p>
</blockquote>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /> Ich glaube, ich habe Templates und std::string unterschätzt, das löst natürlich alles. Danke!</p>
<p>Äh.. da kommt gleich die nächste Frage auf:<br />
Kann man es irgendwie vermeiden, Templates im Funktionsrumpf zu definieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098090</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:30:57 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:35:03 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Kann man es irgendwie vermeiden, Templates im Funktionsrumpf zu definieren?</p>
</blockquote>
<p>Du kannst Templates forward-deklarieren, wenn du das meinst. Verstehe ich dich da richtig?</p>
<p>Natürlich muss wie üblich die Definition zum Zeitpunkt der Instanzierung verfügbar sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098097</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098097</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:35:03 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 17:59:13 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Verstehe ich dich da richtig?</p>
</blockquote>
<p>Ne, wollte sagen: &quot;vermeiden sie im Header zu definieren&quot;.<br />
Denn ich habe hier eine Klasse, die quasi nur aus Templates besteht. Das Ganze ist natürlich irgendwie nervig, da ich so die Klasse komplett im Header definieren muss. (Und sie ist doch recht umfangreich.)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098108</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098108</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 17:59:13 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 18:01:44 GMT]]></title><description><![CDATA[<p>Ich sehe das Problem nicht:</p>
<pre><code class="language-cpp">//Template.hpp
template&lt;class T&gt;
class Foo
{
  template&lt;class U&gt;
  void Bar(const U&amp;) const;
};
//Template.cpp
template&lt;class T&gt;
template&lt;class U&gt;
void Foo&lt;T&gt;::Bar(const U&amp;) const
{
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2098110</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098110</guid><dc:creator><![CDATA[EOutOfResources]]></dc:creator><pubDate>Tue, 26 Jul 2011 18:01:44 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 18:08:15 GMT]]></title><description><![CDATA[<p>cooky451: Du kannst die Deklarationen in den Header schreiben und am Ende des Headers eine .impl inkludieren. Dann hast du ein wenig Übersicht in der .h-Datei.</p>
<p>EOutOfResources: Die Definition muss zum Zeitpunkt des Aufrufs bekannt sein. Du kannst deine Funktion also nicht in einer anderen Übersetzungseinheit benutzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098113</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098113</guid><dc:creator><![CDATA[Michael E.]]></dc:creator><pubDate>Tue, 26 Jul 2011 18:08:15 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 18:17:56 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Ich glaube, ich habe Templates und std::string unterschätzt, das löst natürlich alles. Danke!</p>
</blockquote>
<p>Mit <code>std::string</code> hat dieser Ansatz übrigens gar nichts zu tun. Übergib lediglich zwei <code>char</code> -Zeiger auf Beginn und Ende (bzw. danach) der Zeichenkette, Zeiger sind in diesem Fall deine Iteratoren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098119</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098119</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 26 Jul 2011 18:17:56 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 18:28:47 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Mit <code>std::string</code> hat dieser Ansatz übrigens gar nichts zu tun. Übergib lediglich zwei <code>char</code> -Zeiger auf Beginn und Ende (bzw. danach) der Zeichenkette, Zeiger sind in diesem Fall deine Iteratoren.</p>
</blockquote>
<p>Du weißt doch gar nicht, was foo() mit den Iteratoren macht. Darauf bezog sich die Bemerkung. <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>Michael E. schrieb:</p>
<blockquote>
<p>Dann hast du ein wenig Übersicht in der .h-Datei.</p>
</blockquote>
<p>Hm.. ok, aber mich stört vor allem das ständige Neukompilieren. Vermutlich lässt sich das gar nicht vermeiden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098126</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098126</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 18:28:47 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 18:47:20 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Du weißt doch gar nicht, was foo() mit den Iteratoren macht.</p>
</blockquote>
<p>Das kann mir auch egal sein. Darin besteht ja gerade der Sinn, Iteratoren als Abstraktion zu verwenden. Wenn du intern was <code>std::string</code> -spezifisches machst, ist deine Schnittstelle nicht generisch genug, obwohl sie es behauptet zu sein.</p>
<p>cooky451 schrieb:</p>
<blockquote>
<p>Hm.. ok, aber mich stört vor allem das ständige Neukompilieren. Vermutlich lässt sich das gar nicht vermeiden.</p>
</blockquote>
<p>Nein. Aber du kannst natürlich Code, der nicht von Template-Parametern abhängt, in separate Übersetzungseinheiten auslagern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098134</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098134</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Tue, 26 Jul 2011 18:47:20 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 20:10:44 GMT]]></title><description><![CDATA[<p>Hmja, ich bin gerade etwas am experimentieren - die Ergebnisse sind aber irgendwie gar nicht zu gebrauchen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
<pre><code class="language-cpp">#include &lt;ctime&gt;
#include &lt;iostream&gt;
#include &lt;utility&gt;

int foo(const std::string&amp; s)
{
  return s.end() - s.begin();
}
int foo(const std::pair&lt;std::string::const_iterator, std::string::const_iterator&gt; p)
{
  return p.second - p.first;
}
int foo(std::string::const_iterator begin,
  std::string::const_iterator end)
{
  return end - begin;
}
int foo2(const std::pair&lt;std::string::const_iterator, std::string::const_iterator&gt;&amp; p) // &amp;
{
  return p.second - p.first;
}
int foo(const std::string::const_iterator* its)
{
  return its[1] - its[0];
}

int bar(std::string::const_iterator begin,
  std::string::const_iterator end)
{
  int b = 0;
  for (int i = 0; i &lt; 25000000; ++i)
    b += foo(std::string(begin, end));
  return b;
}
int bar2(std::string::const_iterator begin,
  std::string::const_iterator end)
{
  int b = 0;
  for (int i = 0; i &lt; 25000000; ++i)
    b += foo(std::pair&lt;std::string::const_iterator, std::string::const_iterator&gt;(begin, end));
  return b;
}
int bar3(std::string::const_iterator begin,
  std::string::const_iterator end)
{
  int b = 0;
  for (int i = 0; i &lt; 25000000; ++i)
    b += foo(begin, end);
  return b;
}
int bar4(std::string::const_iterator begin,
  std::string::const_iterator end)
{
  int b = 0;
  for (int i = 0; i &lt; 25000000; ++i)
    b += foo2(std::pair&lt;std::string::const_iterator, std::string::const_iterator&gt;(begin, end));
  return b;
}
int bar5(std::string::const_iterator begin,
  std::string::const_iterator end)
{
  int b = 0;
  std::string::const_iterator its[] = {begin, end};
  for (int i = 0; i &lt; 25000000; ++i)
    b += foo(its);
  return b;
}

int main()
{
  std::string s = &quot;Hello, world!&quot;;

  std::clock_t t = std::clock();
  std::cout &lt;&lt; &quot;string const&amp;: &quot; &lt;&lt; bar(s.begin(), s.end());
  std::cout &lt;&lt; &quot;\t\tTime: &quot; &lt;&lt; std::clock() - t &lt;&lt; std::endl;

  t = std::clock();
  std::cout &lt;&lt; &quot;pair: &quot; &lt;&lt; bar2(s.begin(), s.end());
  std::cout &lt;&lt; &quot;\t\tTime: &quot; &lt;&lt; std::clock() - t &lt;&lt; std::endl;

  t = std::clock();
  std::cout &lt;&lt; &quot;direct: &quot; &lt;&lt; bar3(s.begin(), s.end());
  std::cout &lt;&lt; &quot;\t\tTime: &quot; &lt;&lt; std::clock() - t &lt;&lt; std::endl;

  t = std::clock();
  std::cout &lt;&lt; &quot;pair const&amp;: &quot; &lt;&lt; bar4(s.begin(), s.end());
  std::cout &lt;&lt; &quot;\t\tTime: &quot; &lt;&lt; std::clock() - t &lt;&lt; std::endl;

  t = std::clock();
  std::cout &lt;&lt; &quot;direct array: &quot; &lt;&lt; bar5(s.begin(), s.end());
  std::cout &lt;&lt; &quot;\t\tTime: &quot; &lt;&lt; std::clock() - t &lt;&lt; std::endl;

  std::cin.get();
}
</code></pre>
<p>Visual Studio 2010 (Standard Release): ~<br />
string const&amp;: 534<br />
pair: 1<br />
direct: 20 (???)<br />
pair const&amp;: 17 (???)<br />
direct array: 17</p>
<p>GCC 4.5.2 (Windows, O2): ~<br />
string const&amp;: 11294 (???)<br />
pair: 1<br />
direct: 1<br />
pair const&amp;: 1<br />
direct array: 1</p>
<p>WTF mache ich falsch? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098171</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098171</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 20:10:44 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 20:22:23 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>WTF mache ich falsch? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
</blockquote>
<p>bar() erzeugt in jedem Schleifendurchlauf einen neuen temporären String, in den es den Inhalt von s reinkopiert (inklusive Speicheranforderung und -freigabe), die übrigen Funktionen hantieren alle mit Iteratoren auf den ursprünglich in der main() angelegten String. Die Unterschiede bei den anderen Funktionen könnten durch unterschedlich gute Optimierungen zustandekommen und durch die Anzahl der benötigten Kopien (foo(pair) und foo(iterator,iterator) müssen je zwei Iteratoren bei der Parameterübergabe kopieren, foo2(const pair&amp;) und foo(iterator[]) nur eine Adresse).</p>
<p>PS: Haben diese Funktionen einen tieferen Sinn?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098177</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098177</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 26 Jul 2011 20:22:23 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 20:44:48 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>bar() erzeugt in jedem Schleifendurchlauf einen neuen temporären String, in den es den Inhalt von s reinkopiert (inklusive Speicheranforderung und -freigabe),</p>
</blockquote>
<p>Das war der Plan. Bzw. der Plan war zu sehen wie gut der Compiler hier optimiert. Mich wundert nur der krasse Unterschied zwischen VS und GCC. (-O3 hilft auch nicht wirklich.)</p>
<p>CStoll schrieb:</p>
<blockquote>
<p>Die Unterschiede bei den anderen Funktionen könnten durch unterschedlich gute Optimierungen zustandekommen</p>
</blockquote>
<p>Soweit war ich auch. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>CStoll schrieb:</p>
<blockquote>
<p>und durch die Anzahl der benötigten Kopien (foo(pair) und foo(iterator,iterator) müssen je zwei Iteratoren bei der Parameterübergabe kopieren, foo2(const pair&amp;) und foo(iterator[]) nur eine Adresse).</p>
</blockquote>
<p>Und hier wird es spannend. Hast du dir die Ergebnisse überhaupt richtig durchgelesen? Unter VS ist std::pair&lt;&gt; 20 mal(!) schneller als std::pair const&amp; oder eine direkte Parameterübergabe! (Edit: Man könnte argumentieren, dass die Dereferenzierung teuer ist. Allerdings verstehe ich nicht, warum VS das nicht einfach wegoptimiert. GCC schafft das doch auch!)</p>
<p>CStoll schrieb:</p>
<blockquote>
<p>PS: Haben diese Funktionen einen tieferen Sinn?</p>
</blockquote>
<p>Na, nicht direkt. Ich wollte eigentlich nur gucken wie viel std::string kaputt macht und da hat Eins zum Anderen geführt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098191</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 20:44:48 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:00:14 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>CStoll schrieb:</p>
<blockquote>
<p>bar() erzeugt in jedem Schleifendurchlauf einen neuen temporären String, in den es den Inhalt von s reinkopiert (inklusive Speicheranforderung und -freigabe),</p>
</blockquote>
<p>Das war der Plan. Bzw. der Plan war zu sehen wie gut der Compiler hier optimiert. Mich wundert nur der krasse Unterschied zwischen VS und GCC. (-O3 hilft auch nicht wirklich.)</p>
</blockquote>
<p>Also entweder der VS ist an der Stelle wirklich besser beim Optimieren oder er hat eine kopierfreundlichere Version von std::string (irgendwas mit Referenzzählung könnte dort helfen, wenn der Iterator weiß, zu wem er gehört).</p>
<blockquote>
<p>CStoll schrieb:</p>
<blockquote>
<p>und durch die Anzahl der benötigten Kopien (foo(pair) und foo(iterator,iterator) müssen je zwei Iteratoren bei der Parameterübergabe kopieren, foo2(const pair&amp;) und foo(iterator[]) nur eine Adresse).</p>
</blockquote>
<p>Und hier wird es spannend. Hast du dir die Ergebnisse überhaupt richtig durchgelesen? Unter VS ist std::pair&lt;&gt; 20 mal(!) schneller als std::pair const&amp; oder eine direkte Parameterübergabe! (Edit: Man könnte argumentieren, dass die Dereferenzierung teuer ist. Allerdings verstehe ich nicht, warum VS das nicht einfach wegoptimiert. GCC schafft das doch auch!)</p>
</blockquote>
<p>Inlining könnte auch eine Rolle spielen - und die Kenntnis des Compilers über die betiligten Datentypen. Hast du denn mal in den Headern nachgesehen, was sich auf beiden Systemen hinter std::string::const_iterator verbirgt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098197</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:00:14 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:43:20 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10318">@CStoll</a>:<br />
MSVC's std::string hat nen eingebauten Puffer (&quot;SSO&quot;) für IIRC 16 Character (oder 16 Bytes? - egal, in dem Fall das selbe).<br />
Der String von cooky ist ausreichend kurz -&gt; booyah <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>MSVC's schlimmste Bremse, der relativ langsame Heap, kommt dadurch nicht zum Zuge.</p>
<p>EDIT: Alles Blödsinn. Hier wird ja sowieso nix kopiert, bloss die Länge auf furchtbar komplizierte Art und Weise ausgerechnet. Und die CLOCKS_PER_SEC Sache muss erstmal bereinigt werden, bevor man irgendwas vergleichen kann.<br />
Eigentlich müsste MSVC hier langsamer sein, wegen der ollen Checked-Iterators.</p>
<p>EDIT2: OK, an einer Stelle wird doch kopiert, hab' ich übersehen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098205</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098205</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:43:20 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:20:49 GMT]]></title><description><![CDATA[<p>@cooky:</p>
<p>Du kannst std::clock() Differenzen verschiedener Compiler nicht unbedingt miteinander vergleichen. Googel mal nach CLOCKS_PER_SEC.</p>
<p>Oder lies da:<br />
<a href="http://www.cplusplus.com/reference/clibrary/ctime/clock/" rel="nofollow">http://www.cplusplus.com/reference/clibrary/ctime/clock/</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098209</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098209</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:20:49 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:32:58 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/10318">@CStoll</a>:<br />
MSVC's std::string hat nen eingebauten Puffer (&quot;SSO&quot;) für IIRC 16 Character (oder 16 Bytes? - egal, in dem Fall das selbe).<br />
Der String von cooky ist ausreichend kurz -&gt; booyah <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>MSVC's schlimmste Bremse, der relativ langsame Heap, kommt dadurch nicht zum Zuge.</p>
<p>EDIT: Alles Blödsinn. Hier wird ja sowieso nix kopiert, bloss die Länge auf furchtbar komplizierte Art und Weise ausgerechnet. Und die CLOCKS_PER_SEC Sache muss erstmal bereinigt werden, bevor man irgendwas vergleichen kann.<br />
Eigentlich müsste MSVC hier langsamer sein, wegen der ollen Checked-Iterators.</p>
</blockquote>
<p>Wow! Tatsache, MSVC macht von &quot;123456789abcdef&quot; auf &quot;123456789abcdefZ&quot; einen Sprung von 543 auf 25545 ms! Den GCC interessiert das gar nicht. Schon lustig, wie unterschiedlich gut die Compiler optimieren.</p>
<p>Edit:<br />
Dein Edit war wohl nix. :p</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Du kannst std::clock() Differenzen verschiedener Compiler nicht unbedingt miteinander vergleichen.</p>
</blockquote>
<p>Ist mir schon bewusst, ich habe nur noch nie erlebt, dass clock() unter Windows etwas anderes als ms zurückgegeben hat (wie auch hier). Ist natürlich trotzdem nicht ganz korrekt, aber ist ja auch nur dreckiger Testcode. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098214</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098214</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:32:58 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:44:05 GMT]]></title><description><![CDATA[<p>OK, alles zurück, DA wird ja doch kopiert</p>
<pre><code class="language-cpp">int bar(std::string::const_iterator begin, 
   std::string::const_iterator end) 
 { 
   int b = 0; 
   for (int i = 0; i &lt; 25000000; ++i) 
     b += foo(std::string(begin, end));  // &lt;------ DAAAAAAA :)
   return b; 
 }
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2098216</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098216</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:44:05 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:47:38 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Wow! Tatsache, MSVC macht von &quot;123456789abcdef&quot; auf &quot;123456789abcdefZ&quot; einen Sprung von 543 auf 25545 ms! Den GCC interessiert das gar nicht. Schon lustig, wie unterschiedlich gut die Compiler optimieren.</p>
</blockquote>
<p>Was hat das mit Optimieren zu tun <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /><br />
Tu mal bei MSVC die Checked Iterator Dingens deaktivieren. Mach mal ein</p>
<pre><code class="language-cpp">#define _SECURE_SCL 0
</code></pre>
<p>in dein Precompiled-Header File rein (stdafx.h), oder falls du keins verwendest, eben irgendwo wo es vor allem anderen steht, und für alle .cpp Files gilt.</p>
<p>Und dann vergleich nochmal.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098217</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098217</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:47:38 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 21:55:19 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Und dann vergleich nochmal.</p>
</blockquote>
<p>Kein Unterschied. Hätte mich jetzt auch etwas überrascht, es werden doch überall Iteratoren verwendet?</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Was hat das mit Optimieren zu tun <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
</blockquote>
<p>Na ja, dass std::pair&lt;&gt; viel schneller als std::pair&lt;&gt; const&amp; ist, finde ich schon komisch. Ich hätte erwartet, dass dem Compiler das egal ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098219</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098219</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 21:55:19 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 22:12:37 GMT]]></title><description><![CDATA[<p>Das sollte einen Unterschied machen, gerade WEIL Iteratoren verwendet werden.</p>
<p>Und nochwas: die Aufslöung von clock() mag 1 msec sein, aber die Genauigkeit von clock() ist auf Windows Systemen üblicherweise max. 15~17 msec.<br />
D.h. ein Unterschied von 1 vs. 17 oder 20 sagt ... nicht sehr viel bis gar nix.</p>
<p>-&gt; QueryPerformanceCounter</p>
<p>EDIT:<br />
Und dann ist der ganze Test eigentlich sowieso Schmarrn, denn bis auf den Aufruf von &quot;foo&quot;, wo der String kopiert werden muss, sollte ein guter Compiler das sowieso alles zu (fast) Nichts optimieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098220</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098220</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 26 Jul 2011 22:12:37 GMT</pubDate></item><item><title><![CDATA[Reply to Optimierung, Templates on Tue, 26 Jul 2011 22:25:33 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Und dann ist der ganze Test eigentlich sowieso Schmarrn, denn bis auf den Aufruf von &quot;foo&quot;, wo der String kopiert werden muss, sollte ein guter Compiler das sowieso alles zu (fast) Nichts optimieren.</p>
</blockquote>
<p>Hatte ich auch erwartet, ist aber wohl nicht der Fall. Bzw. der GCC macht das. VS aber nicht. Wenn man ihn bis 429496729 iterieren lässt, braucht pair&lt;&gt; immer noch 1ms, die anderen drei Version ~244ms. Nimmt man übertriebenderweise mal 4294967295U, braucht VS für alles 0 Sekunden, außer für &quot;direct&quot;, da braucht er 3680ms. Der GCC optimiert weiterhin alles völlig weg. Ich versteh das nicht, also vor allem nicht, was VS da veranstaltet.</p>
<p>(Der eigentliche Ziel war ja eh nur std::string, aber irgendwie interessiert mich das jetzt..)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2098230</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2098230</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Tue, 26 Jul 2011 22:25:33 GMT</pubDate></item></channel></rss>