<?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[ist std::set eine schlechte Wahl?]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>Ich benötige für mein Programm eine Liste, in den ich einige Kennungen speichere. Die Kennungen dürfen in der Liste nur einmal vorkommen. So gesehen befülle ich die Liste beim Programmstart und prüfe hin und wieder, ob sich eine bestimmte Kennung in der Liste befindet.</p>
<p>Für diese Zwecke scheint ja std::set genau das richtige zu sein. Allerdings hatte ich mal irgendwo gelesen, dass man std::set nicht verwenden sollte. Ich weiß nicht mehr wo ich es gelesen hatte und welche Argumente dagegen sprachen. Weiß jemand von euch ob std::set bestimtme Probleme verursachen kann? Gäbe es eventuell bessere alternativen?</p>
<p>In meinem Falle würde ich std::set<a href="std::string" rel="nofollow">std::string</a> nutzen (da ich textbasierte Kennungen verwende).</p>
<p>viele Grüße,<br />
SBond</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/338004/ist-std-set-eine-schlechte-wahl</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 16:11:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/338004.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 17 May 2016 09:06:37 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 09:06:37 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>Ich benötige für mein Programm eine Liste, in den ich einige Kennungen speichere. Die Kennungen dürfen in der Liste nur einmal vorkommen. So gesehen befülle ich die Liste beim Programmstart und prüfe hin und wieder, ob sich eine bestimmte Kennung in der Liste befindet.</p>
<p>Für diese Zwecke scheint ja std::set genau das richtige zu sein. Allerdings hatte ich mal irgendwo gelesen, dass man std::set nicht verwenden sollte. Ich weiß nicht mehr wo ich es gelesen hatte und welche Argumente dagegen sprachen. Weiß jemand von euch ob std::set bestimtme Probleme verursachen kann? Gäbe es eventuell bessere alternativen?</p>
<p>In meinem Falle würde ich std::set<a href="std::string" rel="nofollow">std::string</a> nutzen (da ich textbasierte Kennungen verwende).</p>
<p>viele Grüße,<br />
SBond</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2495959</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495959</guid><dc:creator><![CDATA[SBond]]></dc:creator><pubDate>Tue, 17 May 2016 09:06:37 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 09:33:39 GMT]]></title><description><![CDATA[<p>Wenn es mit akzeptabler Geschwindigkeit tut, was es soll, benutze es.</p>
<p>Die verzeigerten Container wurden entworfen, weil sie theoretisch schneller sind. Mit den heutigen Prozessoren mit mehereren Cacheebenen ist das aber in der Praxis häufig nicht der Fall. Daher lautet die Empfehlung grundsätzlich std::vector. <strong>Aber:</strong> ein set ist für deinen Zweck einfacher zu benutzen und der Geschwindigkeitsvorteil bei wenigen Einträgen eher zu vernachlässigen, auch weil er mit std::string vermutlich gar nicht so groß ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2495966</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495966</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Tue, 17 May 2016 09:33:39 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 09:39:16 GMT]]></title><description><![CDATA[<p>Nachtrag: wenn vorhanden könnte natürlich unordered_set eine gute Alternative sein.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2495969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495969</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Tue, 17 May 2016 09:39:16 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 10:03:17 GMT]]></title><description><![CDATA[<p>vielen Dank. Dann kann ich ja beruhigt sein. Groß wird die Liste nicht (max. 40 Einträge). Ich denke von der performance nimmt sich das alles nicht so viel. Zumal der zugriff auf die Liste eher selten passiert.</p>
<p>vielen Dank <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/2495982</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495982</guid><dc:creator><![CDATA[SBond]]></dc:creator><pubDate>Tue, 17 May 2016 10:03:17 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 10:16:09 GMT]]></title><description><![CDATA[<p>SBond schrieb:</p>
<blockquote>
<p>So gesehen befülle ich die Liste beim Programmstart und prüfe hin und wieder, ob sich eine bestimmte Kennung in der Liste befindet.</p>
</blockquote>
<p>Der vermutlich effizientere Container für dieses vorhaben dürfte ein sortierter <code>std::vector</code> sein. Da du nur einmal am Anfang Werte einfügst, musst du nur einmal sortieren und finden von Elementen geht in <code>O(log N)</code> Schritten mit binärer Suche (genau wie bei <code>std::set</code> , aber vermutlich schneller da im <code>vector</code> alles zusammenhängend gespeichert ist). Den <code>std::unordered_set</code> kann man ja auch mal testen. Bei nur 40 Elementen und wenigen Tests sollte die Performance nicht so eine wichtige Rolle spielen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2495984</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495984</guid><dc:creator><![CDATA[sebi707]]></dc:creator><pubDate>Tue, 17 May 2016 10:16:09 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 10:43:26 GMT]]></title><description><![CDATA[<p>SBond schrieb:</p>
<blockquote>
<p>Groß wird die Liste nicht (max. 40 Einträge). Ich denke von der performance nimmt sich das alles nicht so viel. Zumal der zugriff auf die Liste eher selten passiert.</p>
</blockquote>
<p>Je kleiner die Datenmenge, desto eher ist eigentlich vector die bessere Wahl. set ist ja gerade dazu gut, dass es große Datenmengen clever organisiert, so dass man sich unnötige Zugriffe spart, zum Preis gewisser Mehrkosten pro Zugriff.</p>
<p>Beachte aber auch das was sebi707 gesagt hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2495991</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495991</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 17 May 2016 10:43:26 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 11:17:12 GMT]]></title><description><![CDATA[<p>ok <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>dann bleibe ich wohl doch beim guten alten std::vector <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/2495998</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2495998</guid><dc:creator><![CDATA[SBond]]></dc:creator><pubDate>Tue, 17 May 2016 11:17:12 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 11:22:59 GMT]]></title><description><![CDATA[<p>Der Vector ist immer die erste Wahl. List die schlechteste. Und alles andere (Set, Map usw.), wenn Vector offensichtlich doch Ärger macht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496001</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496001</guid><dc:creator><![CDATA[Artchi]]></dc:creator><pubDate>Tue, 17 May 2016 11:22:59 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Tue, 17 May 2016 15:57:47 GMT]]></title><description><![CDATA[<p>Ist die Liste compilezeitkonstant?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496033</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496033</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 17 May 2016 15:57:47 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 06:43:41 GMT]]></title><description><![CDATA[<p>manni66 schrieb:</p>
<blockquote>
<p>Die verzeigerten Container wurden entworfen, weil sie theoretisch schneller sind. Mit den heutigen Prozessoren mit mehereren Cacheebenen ist das aber in der Praxis häufig nicht der Fall.</p>
</blockquote>
<p>So ein Stuss...</p>
<p>Kennst du überhaupt den Unterschied zwischen O(n*log(n)) und O(log(n))?</p>
<p>Probiere mal folgendes aus:<br />
1.) Initialisiere einen Container mit 1.000.000 Elementen<br />
2.) for i = 0; i &lt; 1000; i++ do<br />
3.) Füge Zufallszahl sortiert in Liste ein<br />
4.) Suche Zufallszahl X und gebe das Ergebnis aus<br />
5.) end for</p>
<p>Nimm am Anfang den std::set Container und wähle das Ende der for Schleife so, dass das Programm 5 Sekunden benötigt. Wenn du nun den Container gegen einen std::vector austauscht, wird sich das Program spürbar verlangsamen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496097</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496097</guid><dc:creator><![CDATA[Bitte ein Bit]]></dc:creator><pubDate>Wed, 18 May 2016 06:43:41 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 07:05:34 GMT]]></title><description><![CDATA[<p>1. 90/10 Regel .... Du hasst also ne chance von 90%, das Dein Code nur unerheblich Auswirkung auf die gesamtperformance hat.<br />
Also wenn dir unsicher bist, welcher container, mach lieber nen &quot;verständliches&quot; interface drum und entscheide dich nach bauchgefühl.<br />
Dann mess die GesamtPerformance ... wenn unzureichend, analysieren und wenn dann doch auf den container stößt ... bist wenigstens vorbererietet ^^</p>
<p>2.</p>
<blockquote>
<p>in den ich einige Kennungen speichere</p>
</blockquote>
<p>Wie der container seine daten anordnet etc ... ist zwar schon wichtig, verblasst aber auch gegenüber der performance der vergleichsoperation ...<br />
Wenn in der situation bist, wo der container nen problem ist, würd ich auch überlegen, ob die kennungen nicht hashen solltest</p>
<p>Ciao ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496098</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496098</guid><dc:creator><![CDATA[RHBaum]]></dc:creator><pubDate>Wed, 18 May 2016 07:05:34 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 09:33:37 GMT]]></title><description><![CDATA[<p>Bitte ein Bit schrieb:</p>
<blockquote>
<p>manni66 schrieb:</p>
<blockquote>
<p>Die verzeigerten Container wurden entworfen, weil sie theoretisch schneller sind. Mit den heutigen Prozessoren mit mehereren Cacheebenen ist das aber in der Praxis häufig nicht der Fall.</p>
</blockquote>
<p>So ein Stuss...</p>
<p>Kennst du überhaupt den Unterschied zwischen O(n*log(n)) und O(log(n))?</p>
</blockquote>
<p>Wenn du manni66s Satz nochmal liest, sollte dir auffallen, dass er auf eine Diskrepanz zwischen Theorie und Praxis hinweist.<br />
In der Theorie sind alle Speicherzugriffe gleich schnell, so dass man auf die Idee kommen könnte, dass sich eine <code>map</code> oder ein <code>set</code> im Vergleich zu einem stupide durchsuchten <code>vector</code> ab einem <code>n</code> von etwa 10 lohnen könnte.<br />
In der Praxis ist die Geschwindigkeit jedoch von der Art und Wiese abhängig, wie ein Algorithmus auf den Speicher zugreift (CPU-Cache), und diesbezüglich stehen <code>map</code> und <code>set</code> nicht sonderlich gut da, so dass das <code>n</code> , ab welchem <code>map</code> und <code>set</code> einen Geschwindigkeitsvorteil bringen, locker 2 bis 3 Größenordnungen höher liegt als man erwarten würde. Meiner Erfahrung nach hat man es, wenn man eine Dictionary-Datenstruktur benötigt, meistens mit einer Anzahl von Elementen zu tun, bei der wahrscheinlich ein dummer <code>vector</code> schneller ist. Für dein Beispiel mit den 1M Elementen dominiert natürlich aller Wahrscheinlichkeit nach die theoretische Überlegenheit von <code>map</code> und <code>set</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496108</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496108</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Wed, 18 May 2016 09:33:37 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 09:46:23 GMT]]></title><description><![CDATA[<p>std::set ist sehr oft eine gute Wahl.</p>
<p>Wenn ich einen Container brauche, wo ein Element nur ein mal vorkommen darf, bzw. soll und ich darin suchen will, dann stellt std::set ein verständliches Interface zur Verfügung. Und das ist zunächst mal das Hauptkriterium.</p>
<p>Verwende ich einen std::vector für den Anwendungsfall, muss ich mich selbst darum kümmern, die Elemente eindeutig zu machen und auch die Suche ist komplizierter. Nicht wirklich kompliziert, aber wie auch immer ich es mache ist es schwieriger lesbar, als bei einem std::set.</p>
<p>Wenn ich mir Gedanken um die Performance mache, dann sollte ich zunächst die Frage stellen, ob die Verwendung des Containers für die Gesamtperformance meines Programmes von Bedeutung ist. Benötige ich genau an dieser Stelle eine exzellente Performance? Ist der Zugriff auf den Container Relevant? Dabei ist zu berücksichtigen, dass ein std::set sehr schnell ist.</p>
<p>Wenn ich zu dem Ergebnis komme, dass der Container einen Engpass darstellen könnte, dann kann ich mir Gedanken machen, ob std::vector hier schneller wäre. Ein std::vector hat von der Performance den Vorteil, dass die Elemente hintereinander im Speicher stehen. Das wird beim std::string allerdings ein wenig abgeschwächt, da er die Daten ja über einen Zeiger indirekt verwaltet (short-string Optimierung mal ausgeklammert).</p>
<p>Auch muss ich mir Gedanken machen, ob nicht der Stringvergleich beim Suchen deutlich mehr Performance benötigt, als die eigentliche Suche.</p>
<p>Bei der linearen Suche in einem std::vector habe ich potentiell mehr Stringvergleiche, als bei einem std::vector. Oder ich halte die Elemente im std::vector immer sortiert. Dann muss ich mich wiederum fragen, wie viel Performance die Sortierung benötigt.</p>
<p>Du siehst also, dass die Antwort viel komplizierter ist. Kurz gesagt, nimm einfach std::set, es sei denn, Du hast gute Gründe, etwas anderes zu nehmen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496112</guid><dc:creator><![CDATA[tntnet]]></dc:creator><pubDate>Wed, 18 May 2016 09:46:23 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 09:54:26 GMT]]></title><description><![CDATA[<p>Bitte ein Bit schrieb:</p>
<blockquote>
<p>manni66 schrieb:</p>
<blockquote>
<p>Die verzeigerten Container wurden entworfen, weil sie theoretisch schneller sind. Mit den heutigen Prozessoren mit mehereren Cacheebenen ist das aber in der Praxis häufig nicht der Fall.</p>
</blockquote>
<p>So ein Stuss...</p>
</blockquote>
<p>Ja?</p>
<blockquote>
<p>Kennst du überhaupt den Unterschied zwischen O(n*log(n)) und O(log(n))?</p>
</blockquote>
<p>Ja, und ich weiß sogar, dass dort eine Konstante c enthalten ist.</p>
<blockquote>
<p>Probiere mal folgendes aus:<br />
1.) Initialisiere einen Container mit 1.000.000 Elementen<br />
2.) for i = 0; i &lt; 1000; i++ do<br />
3.) Füge Zufallszahl sortiert in Liste ein<br />
4.) Suche Zufallszahl X und gebe das Ergebnis aus<br />
5.) end for</p>
<p>Nimm am Anfang den std::set Container und wähle das Ende der for Schleife so, dass das Programm 5 Sekunden benötigt. Wenn du nun den Container gegen einen std::vector austauscht, wird sich das Program spürbar verlangsamen.</p>
</blockquote>
<p>Wenn man das auf aktuellen CPUs misst (Bjarne Stroustrup hat dies z.B. getan), kommt man zu dem überraschenden Ergebnis, das auch bei großem n der vector das set schlägt. Die Erklärung: da beim set durch die Verzeigerung wild im Speicher herum gesprungen wird, muss die CPU auf den langsamen Speicher warten. Währenddessen kann der vector locker n Elemente im Cache verschieben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496113</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496113</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Wed, 18 May 2016 09:54:26 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 09:57:43 GMT]]></title><description><![CDATA[<p>Ja, möglicherweise ist es wirklich mal ein Anwendungsfall. Habe mit std::set noch nicht gearbeitet. Ich werde es einfach mal testen <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/2496114</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496114</guid><dc:creator><![CDATA[SBond]]></dc:creator><pubDate>Wed, 18 May 2016 09:57:43 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Wed, 18 May 2016 18:52:35 GMT]]></title><description><![CDATA[<p>@manni66:<br />
Ich habe es mal getestet so wie es da steht. Ergebnis unter VS2012, Release Version</p>
<p>Zeit bei std::vector : 16797ms<br />
Zeit bei std::set : 0ms</p>
<p>Was soll auch ein Cache machen? Er beschleunigt im Best Case den std::vector Alg. um einen Faktor von 1000. Das dürfte ungefähr der Unterschied Zugriffsgeschwindigkeit L-Cache und Arbeitsspeicher sein. Und dieser Faktor ist konstant! Und je größer die Eingabe wird, desto weniger spielt dieser Faktor eine Rolle.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496166</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496166</guid><dc:creator><![CDATA[Bitte ein Bit]]></dc:creator><pubDate>Wed, 18 May 2016 18:52:35 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 02:15:36 GMT]]></title><description><![CDATA[<p>Bei Keys wo das Vergleichen &quot;teuer&quot; ist (String etc.) sollte ne <code>unordered_map</code> ordentlich was bringen.</p>
<p>Ansonsten könnte bei riesigen Datenmengen evtl. ein B-Baum was bringen. Allerdings auch wieder nicht wenn die Key-Vergleiche zu teuer sind.</p>
<p>tntnet schrieb:</p>
<blockquote>
<p>Du siehst also, dass die Antwort viel komplizierter ist. Kurz gesagt, nimm einfach std::set, es sei denn, Du hast gute Gründe, etwas anderes zu nehmen.</p>
</blockquote>
<p>Genau <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/2496181</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496181</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 19 May 2016 02:15:36 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 07:27:31 GMT]]></title><description><![CDATA[<p>Bitte ein Bit schrieb:</p>
<blockquote>
<p>@manni66:<br />
Ich habe es mal getestet so wie es da steht. Ergebnis unter VS2012, Release Version</p>
<p>Zeit bei std::vector : 16797ms<br />
Zeit bei std::set : 0ms</p>
<p>Was soll auch ein Cache machen? Er beschleunigt im Best Case den std::vector Alg. um einen Faktor von 1000. Das dürfte ungefähr der Unterschied Zugriffsgeschwindigkeit L-Cache und Arbeitsspeicher sein. Und dieser Faktor ist konstant! Und je größer die Eingabe wird, desto weniger spielt dieser Faktor eine Rolle.</p>
</blockquote>
<p>das klingt zumindest seltsam, wie hast du im vector eingefügt und gesucht?</p>
<p>mach den vector sortiert, zum suchen binary search (upper oder lower_bound)<br />
also auch beim einfügen als auch beim lookup<br />
und dann sollte der unterschied bei so kleinen Nummern zumindest unerheblich sein</p>
<p>und dann macht man ganz einfach usecases wo das set oder der vector besser ist, ganz wie man es mag oder jetzt eben braucht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496197</guid><dc:creator><![CDATA[kurze_frage]]></dc:creator><pubDate>Thu, 19 May 2016 07:27:31 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 08:07:39 GMT]]></title><description><![CDATA[<p>Die 0 ms bei <code>std::set</code> erinnern mich gerade an einen Beitrag von Chandler Carruth:<br />
<a href="https://www.youtube.com/watch?v=nXaxk27zwlk&amp;index=4&amp;list=PLHTh1InhhwT75gykhs7pqcR_uSiG601oh" rel="nofollow">https://www.youtube.com/watch?v=nXaxk27zwlk&amp;index=4&amp;list=PLHTh1InhhwT75gykhs7pqcR_uSiG601oh</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496199</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Thu, 19 May 2016 08:07:39 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 09:14:32 GMT]]></title><description><![CDATA[<p>Ein lehrreiches Thema für mich <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>Bin beim googlen auf diese Zusammenfassung gestoßen:</p>
<blockquote>
<p>What is set good for? The point isn't that set is useless-there are times when it's the right choice. We can finally write down the<br />
conditions when it's a better choice than sorted_vector or the equivalent:</p>
<p>- The collection can potentially grow so large that the difference between O(N) and O(log N) is important.</p>
<p>- The number of lookups is the same order of magnitude as the number of insertions; there aren't so few insertions that insertion speed is irrelevant.</p>
<p>- Elements are inserted in random order, rather than being inserted in order.</p>
<p>- Insertions and lookups are interleaved; we don't have distinct insertion and lookup phases. Sometimes all four of these conditions are true. If they are, you should use set; that's what it's designed for.</p>
<p>If any of them are false, though, using such a complicated data structure would be a waste and you could get better performance by using a simple sorted vector.</p>
<p><a href="http://lafstern.org/matt/col1.pdf" rel="nofollow">http://lafstern.org/matt/col1.pdf</a></p>
</blockquote>
<p>Glaube das beschreibt es ganz gut.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496209</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496209</guid><dc:creator><![CDATA[cpp_Jungspund]]></dc:creator><pubDate>Thu, 19 May 2016 09:14:32 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 11:05:42 GMT]]></title><description><![CDATA[<p>kurze_frage schrieb:</p>
<blockquote>
<p>und dann sollte der unterschied bei so kleinen Nummern zumindest unerheblich sein</p>
</blockquote>
<p>Du weisst schon wie viel eine Million mal tausend ist, oder?<br />
Mal 3 GHz angenommen, dann wäre die Konstante bei O(N^2) so bei die 50 Zyklen. Das kommt schon hin.</p>
<p>kurze_frage schrieb:</p>
<blockquote>
<p>und dann macht man ganz einfach usecases wo das set oder der vector besser ist, ganz wie man es mag oder jetzt eben braucht.</p>
</blockquote>
<p>*facepalm*<br />
Du solltest Politiker werden.<br />
Und du solltest nachlesen was der Begriff &quot;use case&quot; bedeuete.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496219</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496219</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 19 May 2016 11:05:42 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 13:39:47 GMT]]></title><description><![CDATA[<p>Bitte ein Bit schrieb:</p>
<blockquote>
<p>@manni66:<br />
Ich habe es mal getestet so wie es da steht.</p>
</blockquote>
<p>Leider lässt sich das nicht übersetzen <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="😉"
    /><br />
Ich habe aber auch ein wenig rumgespielt. Das sollte ungefähr dein Szenario sein.<br />
Leider habe ich hier nur einen Phenom II und zum Vergleich einen alten Celeron M. Wie es auf einer wirklich modernen CPU aussieht muss dann jemand anderes testen.</p>
<p>Der Aufbau ist jedenfalls beim Vector immer schneller und das spätere Einfügen wird am neueren Prozessor stärker beschleunigt als der Rest. Die Konstante ist also größer geworden.</p>
<p>Celeron schrieb:</p>
<blockquote>
<p>Vector:<br />
951464 Elemente in 213ms<br />
896 Elemente eingefügt in 1139ms<br />
73 Elemente gefunden in 1ms</p>
<p>Vector mit bulk insert:<br />
951464 Elemente in 200ms<br />
896 Elemente eingefügt in 156ms<br />
73 Elemente gefunden in 1ms</p>
<p>Set:<br />
951464 Elemente in 1575ms<br />
896 Elemente eingefügt in 2ms<br />
73 Elemente gefunden in 1ms</p>
</blockquote>
<p>Phenom schrieb:</p>
<blockquote>
<p>Vector:<br />
951464 Elemente in 111ms<br />
896 Elemente eingefügt in 232ms<br />
73 Elemente gefunden in 0ms</p>
<p>Vector mit bulk insert:<br />
951464 Elemente in 103ms<br />
896 Elemente eingefügt in 66ms<br />
73 Elemente gefunden in 0ms</p>
<p>Set:<br />
951464 Elemente in 730ms<br />
896 Elemente eingefügt in 1ms<br />
73 Elemente gefunden in 0ms</p>
</blockquote>
<pre><code>#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;set&gt;
#include &lt;algorithm&gt;
#include &lt;chrono&gt;
#include &lt;random&gt;

const int numElem = 1000000;
const int numInsert = 1000;
std::uniform_int_distribution&lt;&gt; dis(1, 10*numElem);

void set_runner()
{
	std::cout &lt;&lt; &quot;Set:\n&quot;;
	auto start = std::chrono::system_clock::now();
	std::set&lt;int&gt; s;
	std::mt19937 gen(42);
	for( int i = 1; i &lt;= numElem; ++i ) {
		s.insert(dis(gen));
	}

	auto fill = std::chrono::system_clock::now();
	std::cout &lt;&lt; s.size() &lt;&lt; &quot; Elemente in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(fill -start).count() &lt;&lt; &quot;ms\n&quot;;

	int count = 0;
	for( int i = 1; i &lt;= numInsert; ++i ) {
		if(s.insert(dis(gen)).second) count++;
	}
	auto insert = std::chrono::system_clock::now();

	std::cout &lt;&lt; count &lt;&lt; &quot; Elemente eingefügt in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(insert - fill).count() &lt;&lt; &quot;ms\n&quot;;

	count = 0;

	for( int i = 1; i &lt;= numInsert; ++i ) {
		if(s.count(dis(gen))) count++;
	}
	auto search = std::chrono::system_clock::now();

	std::cout &lt;&lt; count &lt;&lt; &quot; Elemente gefunden in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(search - insert ).count() &lt;&lt; &quot;ms\n&quot;;

}

void vec_runner()
{
	std::cout &lt;&lt; &quot;Vector: \n&quot;;
	auto start = std::chrono::system_clock::now();
	std::vector&lt;int&gt; v;
	std::mt19937 gen(42);
	for( int i = 1; i &lt;= numElem; ++i ) {
		v.push_back(dis(gen));
	}
	std::sort(begin(v), end(v));
	v.erase( std::unique(begin(v), end(v)), end(v));

	auto fill = std::chrono::system_clock::now();
	std::cout &lt;&lt; v.size() &lt;&lt; &quot; Elemente in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(fill -start).count() &lt;&lt; &quot;ms\n&quot;;

	int count = 0;

	for( int i = 1; i &lt;= numInsert; ++i ) {
		auto val = dis(gen);

		auto it = std::lower_bound(begin(v), end(v), val );

		if( it == end(v) || *it != val) {
			count++;
			v.insert(it, val);
		}
	}
	auto insert = std::chrono::system_clock::now();

	std::cout &lt;&lt; count &lt;&lt; &quot; Elemente eingefügt in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(insert - fill).count() &lt;&lt; &quot;ms\n&quot;;

	count = 0;

	for( int i = 1; i &lt;= numInsert; ++i ) {
		auto val = dis(gen);

		if( std::binary_search(begin(v), end(v), val ) ) count++;
	}

	auto search = std::chrono::system_clock::now();

	std::cout &lt;&lt; count &lt;&lt; &quot; Elemente gefunden in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(search - insert ).count() &lt;&lt; &quot;ms\n&quot;;
}

void vec2_runner()
{
	std::cout &lt;&lt; &quot;Vector mit bulk insert: \n&quot;;
	auto start = std::chrono::system_clock::now();
	std::vector&lt;int&gt; v;
	std::mt19937 gen(42);
	for( int i = 1; i &lt;= numElem; ++i ) {
		v.push_back(dis(gen));
	}
	std::sort(begin(v), end(v));
	v.erase( std::unique(begin(v), end(v)), end(v));

	auto fill = std::chrono::system_clock::now();
	std::cout &lt;&lt; v.size() &lt;&lt; &quot; Elemente in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(fill -start).count() &lt;&lt; &quot;ms\n&quot;;

	int count = v.size();

	for( int i = 1; i &lt;= numInsert; ++i ) {
		v.push_back(dis(gen));
	}
	std::sort(begin(v), end(v));
	v.erase( std::unique(begin(v), end(v)), end(v));
	count = v.size() - count;
	auto insert = std::chrono::system_clock::now();

	std::cout &lt;&lt; count &lt;&lt; &quot; Elemente eingefügt in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(insert - fill).count() &lt;&lt; &quot;ms\n&quot;;

	count = 0;

	for( int i = 1; i &lt;= numInsert; ++i ) {
		auto val = dis(gen);

		if( std::binary_search(begin(v), end(v), val ) ) count++;
	}

	auto search = std::chrono::system_clock::now();

	std::cout &lt;&lt; count &lt;&lt; &quot; Elemente gefunden in &quot; &lt;&lt; std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(search - insert ).count() &lt;&lt; &quot;ms\n&quot;;
}

int main()
{
	vec_runner();
	std::cout &lt;&lt; &quot;\n\n&quot;;
	vec2_runner();
	std::cout &lt;&lt; &quot;\n\n&quot;;
	set_runner();
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2496250</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496250</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Thu, 19 May 2016 13:39:47 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 14:26:41 GMT]]></title><description><![CDATA[<p>manni66 schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Wenn du jetzt noch <code>std::vector&lt;..&gt;::reserve(..)</code> aufrufst, wo es möglich ist, sollte das Füllen noch schneller werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496254</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496254</guid><dc:creator><![CDATA[theta]]></dc:creator><pubDate>Thu, 19 May 2016 14:26:41 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 14:36:22 GMT]]></title><description><![CDATA[<p>theta schrieb:</p>
<blockquote>
<p>manni66 schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Wenn du jetzt noch <code>std::vector&lt;..&gt;::reserve(..)</code> aufrufst, wo es möglich ist, sollte das Füllen noch schneller werden.</p>
</blockquote>
<p>Das bewegt sich im Rahmen der Messungenauigkeit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496255</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496255</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Thu, 19 May 2016 14:36:22 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 15:34:37 GMT]]></title><description><![CDATA[<pre><code>#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;set&gt;

#include &lt;Windows.h&gt;
#include &lt;iostream&gt;

int main(int argc, char** args)
{
	std::vector&lt;int&gt; L;
	//std::set&lt;int&gt; L;
	unsigned long R = 0;
	DWORD T0, T1;

	for (int i = 0; i &lt; 1000000; i++)
		//L.insert(i);
		L.push_back(i);
	std::cout &lt;&lt; &quot;Ok starte Messung\n&quot;;
	T0 = GetTickCount(); // bestimmt die Anzahl der vergangenen Millisekunden seit den Start des OS
	for (int i = 0; i &lt; 1000; i++)
	{
		int v = i * 33 + 111;

		L.push_back(v);
		std::sort(L.begin(), L.end());
		if (std::binary_search(L.begin(), L.end(), v + 1))
			R += (v + 1);

		/*L.insert(v);
		auto f = L.find(v + 1);
		if (f != L.end())
			R += (v + 1);*/
	}
	T1 = GetTickCount();	
	std::cout &lt;&lt; &quot;R: &quot; &lt;&lt; R &lt;&lt; &quot; Zeit: &quot; &lt;&lt; T1 - T0 &lt;&lt; &quot; ms\n&quot;;
	std::cin.get();
	return 0;
}
</code></pre>
<p>Mein Code mit dem ich die Messung durchführte...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496261</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496261</guid><dc:creator><![CDATA[Bitte ein Bit]]></dc:creator><pubDate>Thu, 19 May 2016 15:34:37 GMT</pubDate></item><item><title><![CDATA[Reply to ist std::set eine schlechte Wahl? on Thu, 19 May 2016 17:43:10 GMT]]></title><description><![CDATA[<pre><code>map:    R: 2266476762 Zeit: 47 ms
vector: R: 2266476762 Zeit: 15 ms
</code></pre>
<pre><code>#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;set&gt;

#include &lt;Windows.h&gt;
#include &lt;iostream&gt;

int main(int argc, char** args)
{
    std::vector&lt;int&gt; L;
    //std::set&lt;int&gt; L;
    unsigned long R = 0;
    DWORD T0, T1;

    for (int i = 0; i &lt; 1000000; i++)
        //L.insert(i);
        L.push_back(i);
    std::cout &lt;&lt; &quot;Ok starte Messung\n&quot;;
    T0 = GetTickCount(); // bestimmt die Anzahl der vergangenen Millisekunden seit den Start des OS
    for (int i = 0; i &lt; 100000; i++)
    {
        int v = i * 33 + 111;

		auto it = std::lower_bound(L.begin(), L.end(), v);
        if(it != L.end() &amp;&amp; *it != v)
			L.insert(it, v);
		if (std::binary_search(L.begin(), L.end(), v + 1))
            R += (v + 1);

        /*L.insert(v);
        auto f = L.find(v + 1);
        if (f != L.end())
            R += (v + 1);*/
    }
    T1 = GetTickCount();   
    std::cout &lt;&lt; &quot;R: &quot; &lt;&lt; R &lt;&lt; &quot; Zeit: &quot; &lt;&lt; T1 - T0 &lt;&lt; &quot; ms\n&quot;;
    std::cin.get();
    return 0;
}
</code></pre>
<p>Edit: <code>it != L.end() &amp;&amp;</code><br />
Kein messbarer Unterschied in der Laufzeit.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2496268</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2496268</guid><dc:creator><![CDATA[Caligulaminus]]></dc:creator><pubDate>Thu, 19 May 2016 17:43:10 GMT</pubDate></item></channel></rss>