Set- und Getterfunktionen verwenden oder nicht?
-
Nexus schrieb:
static std::string String; String = CharArray; Function(String);vs.
Function(CharArray);Tzzt, Tzzt..
Wenn, dann sieht das so aus:
const static std::string sorryNotPossibleString = "Sorry, Not Possible."; Function(sorryNotPossibleString);vs.
Function("Sorry, Not Possible.");Und das für einen Bruchteil der CPU Zeit, das isses Wert.
mfg, René~
-
NewSoftzzz schrieb:
Jetzt weißt du, wer sowas macht, Leute, die den Client nicht ändern können

Deine Erkenntnis beruht immer wie mehr auf eine sehr spezielle Situation.

Im übrigen:
Was machtsendMessageToPlayer? Braucht die Funktion überhaupt einenstd::string? Würde nicht auch einchar const*reichen?
-
NewSoftzzz schrieb:
Tzzt, Tzzt..
Wenn, dann sieht das so aus:
Äh, ja. Rate mal, warum ich dich nochmals an deine Aussage erinnert habe. Du hast die Allgemeingültigkeit sogar speziell betont. Um das nochmals zu markieren:
NewSoftzzz schrieb:
Ich meinte nur generell, jede Funktion, die eine std::string Referenz als Parameter hat, sollte man mit nem statischen std::string aufrufen.
Und sowas ist einfach alles andere als sinnvoll. Wenn du das nicht so gemeint hast, dann formuliere es nächstes Mal anders. Wenn dir ein Fehler passiert, kannst du ja immer noch nachträglich dazu Stellung nehmen.
(Dazu kämen all die anderen unsinnigen Fälle wie der folgende, welche von dieser Aussage eingeschlossen werden. Ich glaube dir gerne, dass du das nicht so machst, aber dann relativiere solche Sätze bitte. Tut mir leid für die Haarspalterei, doch du scheinst deinen Fehler bisher nicht einzusehen.)
static std::string String; String = OtherString; // OtherString ist nicht-statischer std::string Function(String); // Funktion muss aber mit statischem String aufgerufen werdenNewSoftzzz schrieb:
Und das für einen Bruchteil der CPU Zeit, das isses Wert.
Nochmals: Die Fälle, in denen man eine Funktion (z.B. Datei-Laden) derart oft mit dem gleichen Argument aufruft, dass es tatsächlich performancekritisch werden könnte, sind Ausnahmen. Und natürlich würde ich das Argument dort auch zwischenspeichern (ob
staticdafür angebracht ist, hängt von der Situation ab). Aber ich wiederhole mich.
-
NewSoftzzz schrieb:
Soll ich hier etwas die sendMessage Funktion duplizieren, einmal für enums und einmal für normale Strings? Nein, ich denke nicht.
Nö, hier mache enums natürlich keinen wirklichen Sinn. Allerdings musst du sowas sicher auch nicht zehntausende Male pro Sekunde schicken. Es sei denn, die ganze Server/Client-Kommunikation läuft in Textform ab.
Was hier übrigens mehr Sinn macht, ist der Haupt-sendMessageToPlayer-Funktion const char* und die Länge des Strings als Parameter zu geben. Da sie wahrscheinlich außer Kopieren oder an send() übergeben nichts mehr mit dem String macht, kannst du auf std::string-Funktionen dort verzichten. Und dann jeweils zwei überladene Funktionen sendMessageToPlayer(const std::string&) und sendMessageToPlayer(const char*), welche dir Ursprungsfunktion mit den richtigen Parametern aufrufen. Dann brauchst du das static string-Gedöns nicht mehr, denn strlen in der zweiten überladenen Funktion kann zur Kompilierzeit ausgewertet werden.
-
[Ghost] schrieb:
Was macht
sendMessageToPlayer? Braucht die Funktion überhaupt einenstd::string? Würde nicht auch einchar const*reichen?Darum geht's doch gar nicht! Ist doch scheiß egal, ob man die FUNKTION auch anders machen kann, wir reden hier von nem zur Compilezeit feststehenden String, den man an ne Methode übergibt, die ne std::string Referenz haben will. Die Frage ist hier nur, c-string oder static std::string.
Nexus schrieb:
Du hast die Allgemeingültigkeit sogar speziell betont. Um das nochmals zu markieren:
NewSoftzzz schrieb:
Ich meinte nur generell, jede Funktion, die eine std::string Referenz als Parameter hat, sollte man mit nem statischen std::string aufrufen.
Und sowas ist einfach alles andere als sinnvoll.
Und dazu stehe ich auch jetzt noch. Es IST allgemeingültig, dafür ist der Performanceunterschied einfach zu hoch, dass die EINE Zeile mehr Code OHNE IRGENDWELCHE Nachteile nicht benutzt werden sollte!!! Siehe benchmark.
Benchmark fertig:
#include <sys/time.h> struct timeval tv; int myint; void benchmark(const std::string& input) { myint += input.size(); } int main() { gettimeofday(&tv, NULL); uint64_t start = tv.tv_sec*1000 + (tv.tv_usec / 1000); myint = 0; for(uint64_t i=0; i< 100 * 1000 * 1000; i++) benchmark("This is for all the nonbelievers out there, who think that they shouldn't follow this rule."); gettimeofday(&tv, NULL); uint64_t end = tv.tv_sec*1000 + (tv.tv_usec / 1000); std::cout << myint << ": " << (end - start) << std::endl; gettimeofday(&tv, NULL); start = tv.tv_sec*1000 + (tv.tv_usec / 1000); myint = 0; static const std::string messageToNonbelievers = "This is for all the nonbelievers out there, who think that they shouldn't follow this rule."; for(uint64_t i=0; i< 100 * 1000 * 1000; i++) benchmark(messageToNonbelievers); gettimeofday(&tv, NULL); end = tv.tv_sec*1000 + (tv.tv_usec / 1000); std::cout << myint << ": " << (end - start) << std::endl; }Ergebnis:
510065408: 12735
510065408: 775Faktor 16,4 !!!
Und das ist noch nicht mal der komplette Faktor, da ja ein Großteil der Ressourcen für die Schleife, den Funktionsaufruf, die Addierung der size() etc. draufgeht. Und trotzdem haben wir einen Faktor von 16,4! Der komplette Funktionsaufruf braucht 16,4 mal mehr so lange! Und das nur weil man statt "const static std::string" einen c-string benutzt.
Also mal ehrlich Jungs, seht es ein, die eine Zeile Code ist hier völlig gerechtfertigt und macht bei nem Variablennamen, der den String zusammenfasst, den Code auch nicht unleserlicher.
Nexus schrieb:
Tut mir leid für die Haarspalterei, doch du scheinst deinen Fehler bisher nicht einzusehen.
16,4 fache Ausführungszeit, nur damit man eine Zeile Code einsparen kann? Und das OHNE JEDEN VORTEIL, nur um etwas weniger Code tippen?? Da kann ich auch direkt PHP programmieren.
SRSLY?
Wer sieht seinen Fehler nicht ein?
mfg, René~
-
@NewSoftzzz
Das Ergebnis ist nur insofern verwunderlich, dass der Unterschied so gering ist. Im ersteren Fall dürfte der gesamte benchmark-Aufruf auf eine, höchstens zwei Assemblerinstruktionen reduziert werden können, im zweiten Fall muss mit new neuer Speicher für eine Stringkopie angefordert werden und dann eben noch kopiert werden.
Ist aber nicht der Punkt, denn außer in diesem Testprogramm reduziert sich dadurch keine Laufzeit ums 16-fache. Außer in Situationen, wo intensiv mit Strings gearbeitet wird, wird der Unterschied nämlich nicht messbar, geschweige denn spürbar sein (also z.B. bei Verwendung in einer Dateiladefunktion).
Wenn du aber eine möglichst performante Verarbeitung von Stringliteralen benötigst, dann liegt es nahe, eine entsprechende Schnittstelle anzubieten, wie ich ja schon vorher gesagt habe. Extrazeilen mit static std::string sind dann ebenfalls nicht nötig.
-
Korrekturen: zweiten*, ersten*
-
;Athar schrieb:
Wenn du aber eine möglichst performante Verarbeitung von Stringliteralen benötigst, dann liegt es nahe, eine entsprechende Schnittstelle anzubieten, wie ich ja schon vorher gesagt habe. Extrazeilen mit static std::string sind dann ebenfalls nicht nötig.
Warum immer so sinnlose Argumente?
ich: "Was ist besser, Apfel oder Birne?"
du: "Schluck eine Vitamintablette, ist effizienter."WTF? Es ist doch scheiß egal, warum die Methode einen "const std::string&" Parameter hat, sie HAT ihn einfach. PUNKT.
Und die Frage lautet bei einer solchen Methode wenn der string schon zur Compilezeit feststeht:
"c-string-literal oder const static std::string"Und die Antwort lautet IMMER:
"const static std::string"Wer jetzt noch widerspricht, bitte Nachteile nennen oder Gegenteil beweisen.
mfg, René~
-
NewSoftzzz schrieb:
Und die Frage lautet bei einer solchen Methode wenn der string schon zur Compilezeit feststeht:
"c-string-literal oder const static std::string"Und die Antwort lautet IMMER:
"const static std::string"Nein, eben nicht! Hast du meinen Post auch nur gelesen?
Die Antwort lautet BEIDES. Wieso weigerst du dich, zwei Zeilen hinzuzufügen, die das Problem endgültig aus der Welt schaffen und bereicherst stattdessen alle möglichen sendMessageToPlayer-Aufrufe mit einer Extrazeile? Vor allem, weil es davon wahrscheinlich nicht wenige geben wird.
-
Athar schrieb:
Wieso weigerst du dich, zwei Zeilen hinzuzufügen, die das Problem endgültig aus der Welt schaffen
DIE METHODE/KLASSE KANN NICHT GEÄNDERT WERDEN.
LERN LESEN!mfg, René~
-
NewSoftzzz schrieb:
Und dazu stehe ich auch jetzt noch. Es IST allgemeingültig, dafür ist der Performanceunterschied einfach zu hoch, dass die EINE Zeile mehr Code OHNE IRGENDWELCHE Nachteile nicht benutzt werden sollte!!! Siehe benchmark.
Okay, dann macht eine weitere Diskussion mit dir wohl nicht allzu viel Sinn.
Alleine dass du vor deinem Edit
static constim Code vergessen hast, zeigt ja, wie wichtig das ist und dass der Vorteil gegenüber einer lokalen Variable hier riesig sein muss. Von den etlichen sinnlosen Anwendungsfälle deines Dogmas, welche ich und andere Leute in diesem Thread nun wirklich zur Genüge erwähnt haben und du trotzdem partout ignorierst, gar nicht zu sprechen.
NewSoftzzz schrieb:
Benchmark fertig:
#include <sys/time.h> struct timeval tv; int myint; void benchmark(const std::string& input) { myint += input.size(); } int main() { gettimeofday(&tv, NULL); uint64_t start = tv.tv_sec*1000 + (tv.tv_usec / 1000); myint = 0; for(uint64_t i=0; i< 100 * 1000 * 1000; i++) benchmark("This is for all the nonbelievers out there, who think that they shouldn't follow this rule."); gettimeofday(&tv, NULL); uint64_t end = tv.tv_sec*1000 + (tv.tv_usec / 1000); std::cout << myint << ": " << (end - start) << std::endl; gettimeofday(&tv, NULL); start = tv.tv_sec*1000 + (tv.tv_usec / 1000); myint = 0; std::string messageToNonbelievers = "This is for all the nonbelievers out there, who think that they shouldn't follow this rule."; for(uint64_t i=0; i< 100 * 1000 * 1000; i++) benchmark(messageToNonbelievers); gettimeofday(&tv, NULL); end = tv.tv_sec*1000 + (tv.tv_usec / 1000); std::cout << myint << ": " << (end - start) << std::endl; }Gut gemacht. Das sagt etwa so viel aus:
float Value = ComputeComplicatedValue(); for (int i = 0; i < 1200; ++i) Function(Value); // braucht 1 Sekundevs.
for (int i = 0; i < 1200; ++i) Function(ComputeComplicatedValue()); // braucht 1200 Sekunden. OMFG Faktor 1200!!!!!Dass ich auf genau diesen Punkt schon mindestens zwei Mal eingegangen bin, brauche ich wohl nicht zu erwähnen.
Aber du kannst dir entweder die Posts von mir und anderen Forenteilnehmern nochmals in Ruhe durchlesen, nachvollziehen und einsehen, dass deine pauschalisierende Aussage der reinste Schwachsinn ist, oder aber du bleibst bei deiner heilen Welt mit
static-Strings. Du hast die Wahl, aber mir fehlt die Lust, um auf diesem Niveau weiterzudiskutieren.
-
NewSoftzzz schrieb:
DIE METHODE/KLASSE KANN NICHT GEÄNDERT WERDEN.
LERN LESEN!Äh, bitte was? Du sagtest, dass du einen Server programmierst und nur der Client nicht von dir ist.
Edit: okay, gut.
Edit2: und genau deswegen ist dein Fall ein Ausnahmefall. Dass man gezwungen ist, an einer performanzkritischen Stelle mit einer unflexiblen Bibliothek arbeiten zu müssen, ist nicht der Regelfall.
-
Nexus schrieb:
Alleine dass du vor deinem Edit
static constim Code vergessen hast, zeigt ja, wie wichtig das ist und dass der Vorteil gegenüber einer lokalen Variable hier riesig sein muss.Das static const braucht man nur, um die Variable über Methodenaufrufe hinweg zu behalten, das ist hier irrelevant, da sich alles in einer Methode abspielt. Und hat nix mit lokalen Variablen zu tun.
Nexus schrieb:
Von den etlichen sinnlosen Anwendungsfälle deines Dogmas, welche ich und andere Leute in diesem Thread nun wirklich zur Genüge erwähnt haben und du trotzdem partout ignorierst, gar nicht zu sprechen.
JEDER, aber auch wirklich JEDER bisherige "sinnlose Anwendungsfall" hat den Bedingungen des Dogmas nicht entsprochen. Aber die muss ich anscheinend in jedem Post wiederholen:
WTF? Es ist doch scheiß egal, warum die Methode einen "const std::string&" Parameter hat, sie HAT ihn einfach. PUNKT. (Die Methode/Klasse ist unveränderbar)
Und die Frage lautet bei einer solchen Methode wenn der string schon zur Compilezeit feststeht:
"c-string-literal oder const static std::string"?Und die Antwort lautet IMMER:
"const static std::string"Zeig mir mal bitte einen bisher geposteten sinnlosen Anwendungsfall / Gegenbeweis, der alle Bedingungen erfüllt?
mfg, René~
-
NewSoftzzz schrieb:
Zeig mir mal bitte einen bisher geposteten sinnlosen Anwendungsfall / Gegenbeweis, der alle Bedingungen erfüllt?
Meine Güte, muss ich mich denn wirklich ständig wiederholen? Lies mal meine Beiträge!
Deine Aussage:
NewSoftzzz schrieb:
Ich meinte nur generell, jede Funktion, die eine std::string Referenz als Parameter hat, sollte man mit nem statischen std::string aufrufen.
Meine Antwort (sei
Function()eine Funktion mitconst std::string&als Parameter). Der folgende Fall wird von deiner Aussage eingeschlossen.Nexus schrieb:
static std::string String; String = OtherString; // OtherString ist nicht-statischer std::string Function(String); // Funktion muss aber mit statischem String aufgerufen werdenSo, und jetzt überleg bitte, bevor du wieder postest!
-
@NewSoftzzz,
Ruhig Blut, es will dich niemand töten
NewSoftzzz schrieb:
WTF? Es ist doch scheiß egal, warum die Methode einen "const std::string&" Parameter hat, sie HAT ihn einfach. PUNKT.
Nein, dass stimmt eben nicht ganz. Wenn man über Performance anfängt zu reden, muss man grössere Bereiche anschauen. Du kannst nicht einfach eine Funktion aus ihrem Kontext reissen, sonst macht die Performance-Überlegung keinen Sinn mehr.
Wie es Nexus gesagt hatte, wenn beim Start des Programmes eine Datei einmal geladen wird und dies über eine Funktion geschieht, welche einen
std::stringerwartet, dann wäre es völliger Unsinn, einenstatic const std::stringzu nehmen, denn du hast dadurch gar keinen Vorteil. Im Gegenteil, die Leserlichkeit geht dadurch verloren. Du verkomplizierst deinen Code unnötig.Deshalb sollten Performance-Überlegungen immer in einem Kontext stehen. Es ist völlig unsinnig, wenn du anfängst Bereiche zu optimieren, welche gar nicht ins Gewicht fallen. Das ist eine Verschwendung Zeit und es hindert zudem noch die Leserlichkeit.
NewSoftzzz schrieb:
JEDER, aber auch wirklich JEDER bisherige "sinnlose Anwendungsfall" hat den Bedingungen des Dogmas nicht entsprochen. Aber die muss ich anscheinend in jedem Post wiederholen:
Wo ist Volkard, wenn man ihn braucht ...
-
[Ghost] schrieb:
Wie es Nexus gesagt hatte, wenn beim Start des Programmes eine Datei einmal geladen wird und dies über eine Funktion geschieht, welche einen
std::stringerwartet, dann wäre es völliger Unsinn, einenstatic const std::stringzu nehmen, denn du hast dadurch gar keinen Vorteil. Im Gegenteil, die Leserlichkeit geht dadurch verloren. Du verkomplizierst deinen Code unnötig.Nun, zugegebenermaßen, eine Stelle die über die komplette Laufzeit nur EIN einziges mal aufgerufen wird, lohnt nicht. Aber ab 2 mal dann schon.
Nehmen wir die Bedingung halt noch dazu: "Der Aufruf muss mindestens 2 mal erfolgen".
mfg, René~
-
Nexus schrieb:
Meine Antwort (sei
Function()eine Funktion mitconst std::string&als Parameter). Der folgende Fall wird von deiner Aussage eingeschlossen.Nexus schrieb:
static std::string String; String = OtherString; // OtherString ist nicht-statischer std::string Function(String); // Funktion muss aber mit statischem String aufgerufen werdenSo, und jetzt überleg bitte, bevor du wieder postest!
Und wie genau steht OtherString jetzt zur Compilezeit fest? Da kann ich nur jemanden quoten:
So, und jetzt überleg bitte, bevor du wieder postest!Wie kann man Programmierer werden, wenn man nicht mal 5 einfache Bedingungen anwenden kann...
mfg, René~
-
NewSoftzzz schrieb:
[Ghost] schrieb:
Wie es Nexus gesagt hatte, wenn beim Start des Programmes eine Datei einmal geladen wird und dies über eine Funktion geschieht, welche einen
std::stringerwartet, dann wäre es völliger Unsinn, einenstatic const std::stringzu nehmen, denn du hast dadurch gar keinen Vorteil. Im Gegenteil, die Leserlichkeit geht dadurch verloren. Du verkomplizierst deinen Code unnötig.Nun, zugegebenermaßen, eine Stelle die über die komplette Laufzeit nur EIN einziges mal aufgerufen wird, lohnt nicht. Aber ab 2 mal dann schon.
Nehmen wir die Bedingung halt noch dazu: "Der Aufruf muss mindestens 2 mal erfolgen".
mfg, René~
Google mal die Bedeutung von folgendem Satz:
"Premature optimizing is the root of all evil"
Und ja, das was Du argumentierst fällt unter diese Regel.
-
loks schrieb:
"Premature optimizing is the root of all evil"
Und ja, das was Du argumentierst fällt unter diese Regel.
Nope, bei dem Satz geht es normalerweise um 5% Leistungsverbesserung bei Verschlechterung der Wartbarkeit.
Bei meinem Dogma geht es um 1640% Leistungsverbesserung ohne Verschlechterung der Wartbarkeit.
mfg, René~
-
NewSoftzzz schrieb:
Nehmen wir die Bedingung halt noch dazu: "Der Aufruf muss mindestens 2 mal erfolgen".
Gut, hier kann ich nun zumindest sagen, dass es einen Vorteil hat. Aber ist der wirklich so wichtig, dass ich den streng nach Dogma immer anwenden sollte? Ich denke eher nicht. Ich programmiere lieber zuerst so, dass man es einfach lesen kann. Zuerst auf die Einfachheit/Lesbarkeit schauen, meinen Code verunstalten kann ich später immer noch.
Vor allem läufst du dann Gefahr, dass du plötzlich überall per
static const std::stringeine Funktion aufrusft und daher grundsätzlich einfach einchar const*gereicht hätte. Und du merkst es nicht einmal
Dogmen sind immer eine gefährliche Sache. Nimm lieber Richtlinien und setze sie hier so fest:
Wenn eine Funktion oft in einem zeitkritischen Bereich aufgerufen wird, einenstd::string const&als Parameter erwartet und man ein Literal übergeben möchte, dann sollte man einenstatic const std::stringverwenden.