<?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[Vector Elementzugriff - Index vs. Iterator]]></title><description><![CDATA[<p>Hi,</p>
<p>ich versuche gerade eine schnellere Lösung für den Zugriff auf Elemente eines zweidimensionalen Vektors zu finden. Der Indexoperator erzeugt nach meinem Verständnis bei jedem Zugriff einen neuen begin() Iterator, also müsste es ja eigentlich schneller sein, den Iterator nur einmal zu erzeugen und zu speichern, richtig?</p>
<p>Also ab zum Testen mit folgender Datenstruktur:</p>
<pre><code class="language-cpp">typedef vector&lt; vector&lt;char&gt; &gt; intvec2D;
typedef vector&lt; vector&lt;char&gt;::iterator &gt; intvec2D_it;

// define 2D-array for visibility data
// also define array of iterators for faster access to ar_vis
intvec2D ar_vis(pbW); 
intvec2D_it ar_vis_its(pbW);

for (int i = 0; i &lt; pbW; i++)
{
	ar_vis[i].resize(pbH);
	ar_vis_its[i] = ar_vis[i].begin();
}

// finally define an iterator for that iterator array
intvec2D_it::iterator ar_vis_it = ar_vis_its.begin();
</code></pre>
<p>Jetzt greife ich auf die Elemente zu, um Index vs. Iterator zu testen:</p>
<pre><code class="language-cpp">for (int i = 0; i &lt; pbW; ++i) 
{
	for (int j = 0; j &lt; pbH; ++j) 
	{
		//const char t = ar_vis[i][j];
		const char t = *(*(ar_vis_it + i) + j);
		if (t &gt;= 1) ++ar_res[ t-1 ];
	}
}
</code></pre>
<p>&quot;ar_vis&quot; ist dabei ziemlich groß, in etwa 1000 * 1000. Der Test mit dem Iterator braucht jetzt in etwa 4x so lang wie das gleiche mit Indexoperator (die auskommentierte Zeile). Diese sequenzielle Schleife kann man ja durchaus noch etwas schneller machen:</p>
<pre><code class="language-cpp">for (int i = 0; i &lt; pbW; ++i) 
{
	vector&lt;char&gt;::iterator tIt = *(ar_vis_it + i);
	for (int j = 0; j &lt; pbH; ++j) 
	{
		const char t = *(tIt + j);
		if (t &gt;= 1) ++ar_res[ t-1 ];
	}
}
</code></pre>
<p>Ist aber immer noch deutlich langsamer. Außerdem brauche ich für reale Anwendungsfälle einen breiter gestreuten Elementzugriff, also nicht mehr sequenziell. Dadurch wird die zweite Methode unbrauchbar.</p>
<p>Ich verstehe nun nicht warum der Zugriff über Iterator so langsam ist. Also was mache ich falsch?</p>
<p>Vielen Dank im Voraus,<br />
Luzzifus.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/262788/vector-elementzugriff-index-vs-iterator</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 08:38:06 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/262788.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 11 Mar 2010 11:54:49 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 11:54:49 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>ich versuche gerade eine schnellere Lösung für den Zugriff auf Elemente eines zweidimensionalen Vektors zu finden. Der Indexoperator erzeugt nach meinem Verständnis bei jedem Zugriff einen neuen begin() Iterator, also müsste es ja eigentlich schneller sein, den Iterator nur einmal zu erzeugen und zu speichern, richtig?</p>
<p>Also ab zum Testen mit folgender Datenstruktur:</p>
<pre><code class="language-cpp">typedef vector&lt; vector&lt;char&gt; &gt; intvec2D;
typedef vector&lt; vector&lt;char&gt;::iterator &gt; intvec2D_it;

// define 2D-array for visibility data
// also define array of iterators for faster access to ar_vis
intvec2D ar_vis(pbW); 
intvec2D_it ar_vis_its(pbW);

for (int i = 0; i &lt; pbW; i++)
{
	ar_vis[i].resize(pbH);
	ar_vis_its[i] = ar_vis[i].begin();
}

// finally define an iterator for that iterator array
intvec2D_it::iterator ar_vis_it = ar_vis_its.begin();
</code></pre>
<p>Jetzt greife ich auf die Elemente zu, um Index vs. Iterator zu testen:</p>
<pre><code class="language-cpp">for (int i = 0; i &lt; pbW; ++i) 
{
	for (int j = 0; j &lt; pbH; ++j) 
	{
		//const char t = ar_vis[i][j];
		const char t = *(*(ar_vis_it + i) + j);
		if (t &gt;= 1) ++ar_res[ t-1 ];
	}
}
</code></pre>
<p>&quot;ar_vis&quot; ist dabei ziemlich groß, in etwa 1000 * 1000. Der Test mit dem Iterator braucht jetzt in etwa 4x so lang wie das gleiche mit Indexoperator (die auskommentierte Zeile). Diese sequenzielle Schleife kann man ja durchaus noch etwas schneller machen:</p>
<pre><code class="language-cpp">for (int i = 0; i &lt; pbW; ++i) 
{
	vector&lt;char&gt;::iterator tIt = *(ar_vis_it + i);
	for (int j = 0; j &lt; pbH; ++j) 
	{
		const char t = *(tIt + j);
		if (t &gt;= 1) ++ar_res[ t-1 ];
	}
}
</code></pre>
<p>Ist aber immer noch deutlich langsamer. Außerdem brauche ich für reale Anwendungsfälle einen breiter gestreuten Elementzugriff, also nicht mehr sequenziell. Dadurch wird die zweite Methode unbrauchbar.</p>
<p>Ich verstehe nun nicht warum der Zugriff über Iterator so langsam ist. Also was mache ich falsch?</p>
<p>Vielen Dank im Voraus,<br />
Luzzifus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867433</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867433</guid><dc:creator><![CDATA[Luzzifus]]></dc:creator><pubDate>Thu, 11 Mar 2010 11:54:49 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:09:31 GMT]]></title><description><![CDATA[<p>Benutze einen Profiler.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867445</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867445</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:09:31 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:16:35 GMT]]></title><description><![CDATA[<p>Wie bitte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867448</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867448</guid><dc:creator><![CDATA[Luzzifus]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:16:35 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:19:12 GMT]]></title><description><![CDATA[<p>Luzzifus schrieb:</p>
<blockquote>
<p>Der Indexoperator erzeugt nach meinem Verständnis bei jedem Zugriff einen neuen begin() Iterator,</p>
</blockquote>
<p>Nein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867449</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867449</guid><dc:creator><![CDATA[CptC]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:19:12 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:20:17 GMT]]></title><description><![CDATA[<p>Ein Profiler sagt dir unter anderem wie oft er welche Funktion/welchen Operator genutzt und wie viel Zeit damit verbraucht wurde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867450</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867450</guid><dc:creator><![CDATA[Fellhuhn]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:20:17 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:34:19 GMT]]></title><description><![CDATA[<p>Das weiß ich doch längst, ich weiß bloß nicht warum b langsamer ist als a.</p>
<p>CptC schrieb:</p>
<blockquote>
<p>Luzzifus schrieb:</p>
<blockquote>
<p>Der Indexoperator erzeugt nach meinem Verständnis bei jedem Zugriff einen neuen begin() Iterator,</p>
</blockquote>
<p>Nein.</p>
</blockquote>
<p>Aha. Trotzdem müsste er in etwa das gleiche tun was ich manuell versuche, oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867452</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867452</guid><dc:creator><![CDATA[Luzzifus]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:34:19 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:45:14 GMT]]></title><description><![CDATA[<p>Übersetz mal im Release-Mode.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867460</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:45:14 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:49:57 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>Übersetz mal im Release-Mode.</p>
</blockquote>
<p>Iteratoren immer noch langsamer als Index, allerdings ist der Unterschied geringer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867463</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867463</guid><dc:creator><![CDATA[Luzzifus]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:49:57 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 12:53:47 GMT]]></title><description><![CDATA[<p>Luzzifus schrieb:</p>
<blockquote>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Übersetz mal im Release-Mode.</p>
</blockquote>
<p>Iteratoren immer noch langsamer als Index, allerdings ist der Unterschied geringer.</p>
</blockquote>
<p>Wenn Du den Microsoftschen Compiler benutzt, sind vielleicht noch checked Iterators an. Guck Dir in dem Fall mal <a href="http://msdn.microsoft.com/en-us/library/aa985896%28VS.80%29.aspx" rel="nofollow">diesen Artikel</a> an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867466</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867466</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 11 Mar 2010 12:53:47 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 13:04:31 GMT]]></title><description><![CDATA[<p>Tachyon schrieb:</p>
<blockquote>
<p>Wenn Du den Microsoftschen Compiler benutzt, sind vielleicht noch checked Iterators an. Guck Dir in dem Fall mal <a href="http://msdn.microsoft.com/en-us/library/aa985896%28VS.80%29.aspx" rel="nofollow">diesen Artikel</a> an.</p>
</blockquote>
<p>Danke für den Artikel, sehr interessant! Ja, ich benutzt Visual Studio 2005.</p>
<p>Ich habs mal explizit deaktiviert. Im Debug Mode hats keinen Unterschied gebracht, im Release Mode sind jetzt alle drei Varianten zumindest gleich schnell.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867479</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867479</guid><dc:creator><![CDATA[Luzzifus]]></dc:creator><pubDate>Thu, 11 Mar 2010 13:04:31 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 13:07:51 GMT]]></title><description><![CDATA[<p>Luzzifus schrieb:</p>
<blockquote>
<p>Tachyon schrieb:</p>
<blockquote>
<p>Wenn Du den Microsoftschen Compiler benutzt, sind vielleicht noch checked Iterators an. Guck Dir in dem Fall mal <a href="http://msdn.microsoft.com/en-us/library/aa985896%28VS.80%29.aspx" rel="nofollow">diesen Artikel</a> an.</p>
</blockquote>
<p>Danke für den Artikel, sehr interessant! Ja, ich benutzt Visual Studio 2005.</p>
<p>Ich habs mal explizit deaktiviert. Im Debug Mode hats keinen Unterschied gebracht, im Release Mode sind jetzt alle drei Varianten zumindest gleich schnell.</p>
</blockquote>
<p>Schneller als <em>äquivalente</em> Indexzugriffe kanns auch nicht sein. Unter der Haube läuft schließlich das Selbe ab.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867481</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867481</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 11 Mar 2010 13:07:51 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 13:13:28 GMT]]></title><description><![CDATA[<p>Ich hatte halt in einer seriös wirkenden Quelle gelesen dass der Index-Operator bei jedem Zugriff einen neuen begin() Iterator erzeugt, daher hatte ich durchaus Hoffnungen. <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/1867483</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867483</guid><dc:creator><![CDATA[Luzzifus]]></dc:creator><pubDate>Thu, 11 Mar 2010 13:13:28 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 16:20:09 GMT]]></title><description><![CDATA[<p>Luzzifus schrieb:</p>
<blockquote>
<p>Ich hatte halt in einer seriös wirkenden Quelle gelesen dass der Index-Operator bei jedem Zugriff einen neuen begin() Iterator erzeugt, daher hatte ich durchaus Hoffnungen. <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>Dann hat die Quelle aber nur seriös gewirkt. Warum sollte da jedesmal ein iterator erzeugt werden?<br />
std::vector ist ja nicht viel mehr als ein gekapseltes dynamisches Array. der Indexzugriff dürfte daher ein entsprechender Indexzugriff auf das zugrundeliegende Array sein. Da std::vector ein Template ist wird der Compiler alle Möglichkeiten haben diesen Indexzugriff zu inlinen.<br />
Ein std::vector&lt;&gt;::iterator dürfte kaum mehr sein als ein gekapselter Pointer auf das Array. Wenn du die ganzen Sicherheitsabfragen ausbaust, die beim MSVC drin sind, dürfte im Releasemodus nach dem (relativ einfachen) Wegoptimieren der ganzen Indirektionen über die Iteratormethoden auch nurnoch ein entsprechend indizierter Zugriff über den internen Pointer des Iterators übrigbleiben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867588</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867588</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Thu, 11 Mar 2010 16:20:09 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 18:33:53 GMT]]></title><description><![CDATA[<p>Luzzifus schrieb:</p>
<blockquote>
<p>Ich hatte halt in einer seriös wirkenden Quelle gelesen dass der Index-Operator bei jedem Zugriff einen neuen begin() Iterator erzeugt, daher hatte ich durchaus Hoffnungen. <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>Das ist eigentlich nicht falsch. operator[] macht ja eigentlich nix anderes, als (vorrausgesetzt, die Iteratoren seien einfache Pointer):</p>
<pre><code class="language-cpp">reference operator[] ( size_type n )
{
    return *(begin() + n); // begin() wird hier eventuell direkt durch den internen Anfangspointer ersetzt
}
</code></pre>
<p>Iteriert werde dabei z.B. folgendermaßen:</p>
<pre><code class="language-cpp">vector&lt;int&gt; v;

// []-Variante
for(size_t i = 0; i &lt; v.size(); ++i) cout &lt;&lt; v[i] &lt;&lt; endl;

// Iteratorvariante
for(vector&lt;int&gt;::iterator i = v.begin(); i != v.end(); ++i) cout &lt;&lt; *i &lt;&lt; endl;
</code></pre>
<p>Bei der []-Variante muss also bei jedem Iterationschritt eine Addition mit 0 bis v.size()-1 durchgeführt werden, bei der Iteratorvariante jeweils eine Addition mit 1 (da ++i). Ich kenne mich jetzt mit den CPU-Implementierung für die Addition nicht so aus, aber wenn es da einen Unterschied gibt, wird der denk ich minimal sein (wobei dann wahrscheinlich die Iteratorvariane sogar schneller wäre).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867654</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867654</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Thu, 11 Mar 2010 18:33:53 GMT</pubDate></item><item><title><![CDATA[Reply to Vector Elementzugriff - Index vs. Iterator on Thu, 11 Mar 2010 18:42:21 GMT]]></title><description><![CDATA[<p>XMaster schrieb:</p>
<blockquote>
<p>Luzzifus schrieb:</p>
<blockquote>
<p>Ich hatte halt in einer seriös wirkenden Quelle gelesen dass der Index-Operator bei jedem Zugriff einen neuen begin() Iterator erzeugt, daher hatte ich durchaus Hoffnungen. <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>Das ist eigentlich nicht falsch. operator[] macht ja eigentlich nix anderes, als (vorrausgesetzt, die Iteratoren seien einfache Pointer):</p>
<pre><code class="language-cpp">reference operator[] ( size_type n )
{
    return *(begin() + n); // begin() wird hier eventuell direkt durch den internen Anfangspointer ersetzt
}
</code></pre>
<p>Iteriert werde dabei z.B. folgendermaßen:</p>
<pre><code class="language-cpp">vector&lt;int&gt; v;

// []-Variante
for(size_t i = 0; i &lt; v.size(); ++i) cout &lt;&lt; v[i] &lt;&lt; endl;

// Iteratorvariante
for(vector&lt;int&gt;::iterator i = v.begin(); i != v.end(); ++i) cout &lt;&lt; *i &lt;&lt; endl;
</code></pre>
<p>Bei der []-Variante muss also bei jedem Iterationschritt eine Addition mit 0 bis v.size()-1 durchgeführt werden, bei der Iteratorvariante jeweils eine Addition mit 1 (da ++i). Ich kenne mich jetzt mit den CPU-Implementierung für die Addition nicht so aus, aber wenn es da einen Unterschied gibt, wird der denk ich minimal sein (wobei dann wahrscheinlich die Iteratorvariane sogar schneller wäre).</p>
</blockquote>
<p>Im Prinzip richtig. Aber das AMD Assembler-Optimierungshandbuch sagt, es ist im Prinzip Wurstegal, weil genau gleichschnell, außer natürlich, wenn man einen Schritt weiterdenkt, und bemerkt, daß die []-Variante gerne mal ein Register weniger braucht, und weniger register pressure ist was tollen, dadurch können globalere Sachen in Register hüpfen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1867666</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1867666</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 11 Mar 2010 18:42:21 GMT</pubDate></item></channel></rss>