Performance: std::string vs. C-Funktionen
-
Hi,
ich habe mal so ne Frage zur Performance im Thema Strings: Nehmen wir an ich habe ein sehr Performance-Kritisches Programm (z. B. Spiel, Wissenschaftliches Programm, Simulation o. Ä.) in dem viel mit Strings im Hintergrund gearbeitet wird.
Ich weiß z. B. aus Erfahrung, dass die C++ Streams recht lam sind, vorallem für den Ausgabe/Eingabe-Puffer oder für Dateien sind die C-Funktionen bzw. API-Funktionen wie printf/WriteConsole und fprintf/WriteFile über 70 - 80% schneller. Auch der Stack-Container ist ja auch nicht grade der Performance-Traum. Diese Klasse besorgt sich halt nur Speicher, wenn er ihn braucht - Klar feine Sache, aber das dauert und wenn viele Elemente reingehen/rausgehen geht das auf Performance.
Doch die Flexibilität der C++ Stringklasse hat es mir kräftig angetan, sowie deren Funktionalität. Aber wie hält es sich mit der Performance? Sollte man die C++ Stringklasse in Performance-Kritischen Programmen benutzen, oder lieber eine Eigenimplementierung, welche die C-Funktionen bzw. API-Funktionen für Strings kapselt?
Danke euch im voraus

-
std::string ist schneller weil die größe mit abgespeichert wird und nicht jedesmal neu berechnet werden muss
-
Zum einen liegt es an dir und nur an dir wenn du mit std::stack unzufrieden bist (Stichwort Allocator).
Zum anderen wirst du std::string auch nicht schneller hinbekommen, es sei denn du optimierst ihn ganz speziell für deinen Zweck.
Die Streams sind etwas vollkommen anderes. Man kann die Streams und C I/O nicht vergleichen, beide haben vollkommen andere Stärken und Schwächen.
-
i schrieb:
std::string ist schneller weil die größe mit abgespeichert wird und nicht jedesmal neu berechnet werden muss
Die kann ich doch ebenfalls zwischenspeichern und die API-String-Funtkionen benutzen, wo ich als Parameter die Länge angeben kann, also daher, ist deine Aussage kein ausschlaggebender Faktor.
-
lolz schrieb:
Zum einen liegt es an dir und nur an dir wenn du mit std::stack unzufrieden bist (Stichwort Allocator).
Das ist mir schon klar, das es nur an mir und zwar nur an mir liegt, wenn ich das benutze, das mit dem Unzufrieden hat eher was mit dem Gebiet zu tun, wo es benutzt wird: In Performance-Kritischen Bereichen.
Dazu musst Du mich nicht wegen dieser Klasse so von der Seite anmachen, hab dir doch gar nichts getan.
-
Das lässt sich sicher nicht so leicht beantworten, da es stark von der Implementierung abhängt. Einige Implementierungen nutzen zB COW für Strings, damit ist das kopieren eines Strings zB ziemlich billig, aber schreib Operationen können teuer sein. Außerdem ist auch die Frage welches Optimierungspotential die Implementierung nutzt. Theoretisch kann eine Implementierung von std::string in vielen Bereichen schneller sein, als die üblichen Operationen auf C-Strings, zB könnte beim kopieren/anhängen spezielle mov-Befehle der CPU genutzt werden, da man die Größe schon kennt und nicht byte-weise kopieren und jedes mal vergleichen muss.
Dir wird also nichts übrig bleiben, als eigene µBenchmarks aufzustellen. Nur bedenke “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.” (Knuth)!
@string-User
ignoriere einfach den Troll. Ein Moderator des Subforums wird den Blödsinn sicher bald entfernen.
-
rüdiger schrieb:
Das lässt sich sicher nicht so leicht beantworten, da es stark von der Implementierung abhängt. Einige Implementierungen nutzen zB COW für Strings, damit ist das kopieren eines Strings zB ziemlich billig, aber schreib Operationen können teuer sein. Außerdem ist auch die Frage welches Optimierungspotential die Implementierung nutzt. Theoretisch kann eine Implementierung von std::string in vielen Bereichen schneller sein, als die üblichen Operationen auf C-Strings, zB könnte beim kopieren/anhängen spezielle mov-Befehle der CPU genutzt werden, da man die Größe schon kennt und nicht byte-weise kopieren und jedes mal vergleichen muss.
Dir wird also nichts übrig bleiben, als eigene µBenchmarks aufzustellen. Nur bedenke “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.” (Knuth)!
@string-User
ignoriere einfach den Troll. Ein Moderator des Subforums wird den Blödsinn sicher bald entfernen.Danke, endlich eine gute Antwort.

-
string-User schrieb:
Auch der Stack-Container ist ja auch nicht grade der Performance-Traum.
Äh? Du meinst den Stack-Container-Adapter? Was ist an dem denn bitte auszusetzen?
Was die Streams betrifft: Kann ich auch nicht nachvollziehen, hängt aber extrem stark von der verwendeten Implementierung ab. 70–80% sind aber in jedem Fall extrem. Gute Implementierungen ziehen in etwa mit C gleich. Das wäre also eher ein Grund, den Compiler bzw. die Implementierung der stdlibc++ zu wechseln. Abgesehen davon benutzt man Streams nur extrem selten in performancekritischen Bereichen.
-
Konrad Rudolph schrieb:
string-User schrieb:
Auch der Stack-Container ist ja auch nicht grade der Performance-Traum.
Äh? Du meinst den Stack-Container-Adapter?
Genau.
-
string-User schrieb:
Auch der Stack-Container ist ja auch nicht grade der Performance-Traum. Diese Klasse besorgt sich halt nur Speicher, wenn er ihn braucht
Ähm .... nein!?!
lolz schrieb:
Zum einen liegt es an dir und nur an dir wenn du mit std::stack unzufrieden bist (Stichwort Allocator).
Allokator? Seit wann hat std::stack einen Allokator?
Weiß hier irgendjemand, wie stack funktioniert?
stack<int, vector<int> > foo; stack<int, dequeue<int> > bar; ...foo wächst so, wie ein vector wächst. Stack ist ja schließlich nur ein Adapter.
bar wächst so, wie eine dequeue wächst. Stack ist ja schließlich nur ein Adapter.
...
-
string-User schrieb:
i schrieb:
std::string ist schneller weil die größe mit abgespeichert wird und nicht jedesmal neu berechnet werden muss
Die kann ich doch ebenfalls zwischenspeichern und die API-String-Funtkionen benutzen, wo ich als Parameter die Länge angeben kann, also daher, ist deine Aussage kein ausschlaggebender Faktor.
Klar kannst du auch alle Performance-Vorteile eines std::strings mit C-Strings erreichen, wenn du alle Vorteile des std::strings nachbaust (zB gespeicherte Länge oä). Aber das ist ja ohnehin klar. Es geht ja um die _normalen_ Fälle (dachte ich zumindest).
-
Helium schrieb:
string-User schrieb:
Auch der Stack-Container ist ja auch nicht grade der Performance-Traum. Diese Klasse besorgt sich halt nur Speicher, wenn er ihn braucht
Ähm .... nein!?!
lolz schrieb:
Zum einen liegt es an dir und nur an dir wenn du mit std::stack unzufrieden bist (Stichwort Allocator).
Allokator? Seit wann hat std::stack einen Allokator?
Weiß hier irgendjemand, wie stack funktioniert?
stack<int, vector<int> > foo; stack<int, dequeue<int> > bar; ...foo wächst so, wie ein vector wächst. Stack ist ja schließlich nur ein Adapter.
bar wächst so, wie eine dequeue wächst. Stack ist ja schließlich nur ein Adapter.
...Und wie holt sich der vector den Speicher? Und wie die dequeue?
-
lolz_ausgeloggt schrieb:
Und wie holt sich der vector den Speicher? Und wie die dequeue?
vector und dequeue haben Allokatoren. Die aussage war jedoch "Diese Klasse besorgt sich halt nur Speicher, wenn er ihn braucht". Und das wird IMHO hier nunmal erstrangig nicht vom Allokator, sondern vom Container an sich bestimmt.
-
leider gibt es bei std::stack kein reserve, womit man schon vorher angeben kann, wieviel Speicher er reservieren soll

std::vector holt sich immer größere Speicherbereiche. Oft sind das 2^n Potenzen. (so könnte man für Typen ohne Copy-Ctor auch gleich effizient kopieren)
-
Helium schrieb:
Weiß hier irgendjemand, wie stack funktioniert?
Ja:
Konrad Rudolph schrieb:
string-User schrieb:
Auch der Stack-Container ist ja auch nicht grade der Performance-Traum.
Äh? Du meinst den Stack-Container-Adapter? Was ist an dem denn bitte auszusetzen?
…