Schnelles C++
-
volkard schrieb:
Vermutlich gehen wir von anderen Betriebsystem-Calls aus. Also ich denke schon dran nullterminirte Strings vom BS zu kriegen, und die beim Abstieg an meinen dranbauen zu müssen. strcat zum Beispiel oder string::+=. Beim Wiederaufstieg kann man in C++ auch wieder kürzen. Ich muss vorher nicht zählen (darf aber, oder darf sinnvoll schätzen), bei Bedarf wächst der string automatisch.
Hast dann aber wieder einen
realloc. Mindestens.
Du nennst es "schätzen", ich würde es "wetten" nennen. Nee, ich gehe immer vom schlimmsten aus. Oder ich bin eher dazu bereit, Speicher zugunsten von Laufzeit zu opfern. Kommt dann aber auch wieder darauf an, für was für eine Plattform man da programmiert. Jenachdem ist dein Ansatz dann wesentlich intelligenter.volkard schrieb:
Jo, ist lästig. Immer, wenns wieder anfängt, daß ich hier als C++-Nube beschimpft werde, weil mein Code zu einfach(lesbar+schnell) ist, poste ich irgendwo ein wenig Template-Gefrickel und hab wieder ein Jahr Ruhe. Ist viel weniger Arbeit, als C++ zu meiden, finde ich.

Ich rede hier nicht mal vom Forum. Da mache ich mir überhaupt nicht die Mühe, den Leuten was beweisen zu wollen.
Ich meine, wenn der Code reviewt wird. Vielleicht habe ich da auch eine Opfermentalität, weil ich selbst so reviews mache, und ständig Code zu sehen bekomme, der stark entweder nach Jürgen "Ich kann alles" Wolf oder von C++ abgeleitet aussieht. In einer Bude lag der Wolf dann auch tatsächlich rum. m(
Jedenfalls versuche ich, mich immer der Mentalität der Sprache anzupassen. Und wenn ich die gleichen Hacks in C++ wie in C anwende und sonst kaum einen der Vorteile von C++, dann kann ich gleich C verwenden. Das kompiliert auch schneller.
-
dachschaden schrieb:
Hast dann aber wieder einen
realloc. Mindestens.
Du nennst es "schätzen", ich würde es "wetten" nennen. Nee, ich gehe immer vom schlimmsten aus. Oder ich bin eher dazu bereit, Speicher zugunsten von Laufzeit zu opfern. Kommt dann aber auch wieder darauf an, für was für eine Plattform man da programmiert. Jenachdem ist dein Ansatz dann wesentlich intelligenter.Wenn ich zufällige Längen zwischn 0 und 999 hätte und 100 "schätzen" würde und 100000 Files hätte, käme ich auf durchschnittlich 7 reallocs. Wobei ich vom dümmlichen
if(r>m){ m=r; realoc(m); }ausginge.
Bezahlbar, finde ich. Hab echt Angst, ich könnte statt der Mikrosekunde fürs reallocen vielleicht zwei Millionen Mikrosekunden ausgeben, um vorher durchzulaufen und die Maxgröße zu finden. Oder ich "wette" einfach, daß 2000 reichen werden und wenn nicht, kracht's eben. Wie stellst Du vorher die maximale Größe fest? Oder haste eine schlichte Garantie wie <=32786 und nimmst einfach die?
Mit m=r+r; bin auch auf 2.4 reallocs.
-
volkard schrieb:
Wie stellst Du vorher die maximale Größe fest? Oder haste eine schlichte Garantie wie <=32786 und nimmst einfach die?
Ich habe eine Funktion, die mir abhängig vom System die maximale Pfadgröße zurückgibt. Mit der arbeite ich. Wenn ich die nicht bekomme, schlägt der Call fehl. Also: Ja, ich suche mir so eine Garantie. Ja, dabei wird Speicher verwendet. Das ist mir klar.
-
dachschaden schrieb:
Ja, dabei wird Speicher verwendet. Das ist mir klar.
Speicher sparen, den kein anderer braucht, ist blöd. Embedded system nehme ich an und singlethreaded. Dann kannste die Garantie einfach benutzen und weiterreichen. Das Wachsen des Speichers, was ich auf PCs bevorzugen würde, könnte dümmstenfalls doppelt so viel Speicher fressen wie das feste Vorallokieren.
Seit ein paar Monaten darf man in C++ keine rohen Zeiger mehr nehmen. Würde ich aber da nehmen, ich Sau.
-
volkard schrieb:
Seit ein paar Monaten darf man in C++ keine rohen Zeiger mehr nehmen.
Sagt wer?
-
EOP schrieb:
volkard schrieb:
Seit ein paar Monaten darf man in C++ keine rohen Zeiger mehr nehmen.
Sagt wer?
Ein Global Moderator.

-
Ich hab kein C++11, also darf ich.
-
Warum hast du kein C++11?
-
Weil ich nur VisulStudio 2005 hab.
-
Warum lädst du dir keine neuere Version runter, oder nimmst MinGW oder Clang? Ich meine, C++11 ist der aktuelle Standard und der nächste steht schon vor der Tür. Ich kenne der alten Standard nicht so, da ich gleich mit C++11 angefangen habe, aber es hat sich ja schon wohl viel geändert.
-
Citizen42 schrieb:
Ich meine, C++11 ist der aktuelle Standard und der nächste steht schon vor der Tür..
Ich finde das toll, dass das so an alle vorbeigeht: C++14 ist schon seit 4 Monaten draußen!
-
Ups echt? Ich dachte irgend ein Draft wäre fertig und muss noch durchgewunken werden.
-
Jup, echt: http://en.wikipedia.org/wiki/C%2B%2B14
-
Jut, dann ab heute -std=c++14 denn das ist ja dann das neue Standard-C++. Sind ja zum Glück nicht so viele Änderungen wie bei C++11.
-
Nathan schrieb:
Jup, echt: http://en.wikipedia.org/wiki/C%2B%2B14
Ich denke der isocpp-Artikel passt hier besser.
Sind ja zum Glück nicht so viele Änderungen wie bei C++11.
Zum Glück?

-
Glück für das wenige Dazulernen von 11 auf 14. Die Änderungen vom alten 98 zu 11 waren ja wohl doch schon viel, aber auch gut, so wie ich das gelesen habe. Ich kenne ja C++98 gar nicht.
Nun haben wir bald 2015 und dann zwei Jahre Zeit bist es wieder was Neues gibt. Bis auf Mircosoft sind ja wohl auch die Features immer recht schnell in den Compilern verfügbar.
-
volkard schrieb:
Speicher sparen, den kein anderer braucht, ist blöd. Embedded system nehme ich an und singlethreaded. Dann kannste die Garantie einfach benutzen und weiterreichen. Das Wachsen des Speichers, was ich auf PCs bevorzugen würde, könnte dümmstenfalls doppelt so viel Speicher fressen wie das feste Vorallokieren.
Naja, ich hab mir schon was dabei überlegt.
Der Programmierer soll zum Beispiel bestimmen können, ob die Funktion jetzt einen Speicher, den er angegeben hat, verwenden soll - in einer Streamer-Struktur, die ich ursprünglich mal für einen IRC-Bot geschrieben habe, aber die hat sich als so vielseitig herausgestellt, dass ich die für das Verzeichnisse-durchlaufen einfach "missbraucht" habe - oder ob die Funktion sich darum kümmert. Der Vorteil ist: die Funktion reserviert den Speicher neu, behält aber originale Daten bei und schaut nur zu, dass am Ende die Daten der rekursiven Funktion geschrieben werden. Der Speicher wird dann nicht freigegeben, weil darum sich der Programmierer kümmern soll, und kann den erweiterten Speicher dann auch für andere Sachen nutzen.
Und wenn er keinen Bock hat, sich um die Speicherverwaltung zu kümmern, gibt er beim Initialcall einfach 0 an, und die Routine kümmert sich selbst darum. Dann gibt die aber den Speicher am Ende wieder frei - der Programmierer wollte ja nicht.Es ist erstaunlich, wie oft man einfach nur einen großen Speicherbereich braucht, und ein bisschen Intelligenz innerhalb seiner Routinen, um sich einen Haufen
malloc/realloc/free-Calls zu spraren. Den gleichen Speicherbereich, den du zum Buffern einer HTTP-Antwort verwendest, kannst du später dazu verwenden, zu ge-entzippen. Und dann später, um wieder in einem Verzeichnis suchen zu lassen und eine Anfrage zu generieren. Wenn man dann noch ein paar PP-Makros definiert, die quasi die Schnittstelle dafür bieten, muss du nur nur 5 weitere Zeilen in deine Funktion unterbringen, und kannst den Durchsatz um einiges erhöhen (waren damals von 50.xxx Cycles auf 10.xxx Cycles runter). Einen HTTP-Parser habe ich so (und ein paar zusätzlichen Tricks) auch von 60.xxx Cycles auf <2.000 Cycles bekommen.
-
Hört sich alles nicht praxisrelevant an. Ein HTTP Parser wird im HTTP Server nicht das Bottleneck sein. Schön, wenn es dir Spass macht, sowas zu optimieren, aber wirklich bringen tut es wohl nichts und führt sehr wahrscheinlich einfach nur zu schlechter wartbarem Code.
-
Ich dachte immer ein Client parst HTML und weniger der Server, der soll doch nur nach Anfrage abliefern, oder nicht? Es sein denn, es sind Serverseitige-Script-Sprachen mit im Spiel, die werden ja vom Server abgearbeitet.
-
Naja, und den ganzen STL Datenstrukturen kann man einen Allokator mitgeben. Ob der jede Speicheranforderung mit einem new Speicher holt oder am Anfang einfach mal 100GB allokiert und diese dann schrittweise rausgibt bleibt dem Entwickler überlassen...