Welche Funktion ist schneller: strcmp oder strlen?



  • knivil schrieb:

    Btw. Was waere denn die Abstraktion fuer "String" + Laenge, wenn moeglich noch mit benutzerfreundlicher Funktionalitaet in C? In C++ ist es std::vector oder std::string!

    std::string => GString
    Ansonsten kann sich das jeder selber schreiben, sind nicht 2000 Zeilen wie in C++, sondern nur 4

    struct benutzerfreundlicherString {
      size_t länge;
      char inhalt[];
    };
    struct benutzerfreundlicherString2 {
      size_t länge;
      char *inhalt;
    };
    

    Ist übrigens um einiges effizienter als C++

    void f(std::string s); // string wird kopiert, ein C++-Programmierer muss höllisch 
                            // aupassen das nicht unabsichtlich hinzuschreiben
    void f(std::string const& s); // indirektion size, doppelte indirektion inhalt
    
    void f(benutzerfreundlicherString *s); // einfache indirektion string+inhalt, nur 1 Pointer parameter
    void f(benutzerfreundlicherString2 s); // nur indirektion für inhalt
    

  • Mod

    objdump schrieb:

    Ansonsten kann sich das jeder selber schreiben, sind nicht 2000 Zeilen wie in C++, sondern nur 4

    Kein Wunder. Der kann schließlich nichts. Wie erzeugt man einen? Wie kopiert man? Wie bekommt man Inhalt hinein? Wie hängt man sie aneinander? Wie durchsucht man die Zeichenkette? Hat der Code auch kein Speicherloch? Was glaubst du, wieso der GString eine so lange Dokumentation (und Implementierung) hat?

    Das sind ganz grundlegende Fragen für die Zeichenkettenverarbeitung. Du darfst zur Implementierung auch gerne string.h benutzen.

    Wenn ich fies wäre, würde ich noch nach Optimierungen (SSO oder COW) fragen, aber ich sehe ja, dass du schon mit den einfachen Dingen überfordert bist.



  • Nun, bei sockets muss ich aber angeben, wieviel ich maximal lesen kann. Diese Groesse ist fix.

    Also die einzigste Einschränkung war bei recv(). Ein Test mit der Puffergröße von 2 Byte funktionierte auch problemlos, er las der Daten immer in 1 Byte Blöcken ein und fügte sie dem std::string hinzu.

    Dann will ich aber nicht zeilenweise lesen, sondern nur bis zum nächsten Komma.

    Sofern die Textdatei ein Komma enthält... Dummes Beispiel, ich weis.

    Dein String-Vorschlag hakt an vielen Ecken und Kanten, wie es SeppJ schon sagt. Spiele doch einfach mal dummer Programmierer und schaue wie sich dein C String verhält.

    benutzerfreundlicherString2 s1, s2;
    
    s1 = malloc(10);
    strcpy(s2.inhalt, "Hallo");
    
    s2 = s1;
    free(s1.inhalt);
    strcpy(s2.inhalt, "Welt");
    

    Ist übrigens um einiges effizienter als C++

    Und schon wieder der Begriff Effizienter? Entschludigung aber so langsam wird in meinen Augen der Begriff Effizienzs ein Indiz für Inkompentenz.

    Dumme Frage. Überprüfst du auch ordentlich ob dein Zeiger auch nicht in Nirwana zeigt. Also überprüfst du auf NULL, 0xCCCCCCCC, ... ?

    Auch ein C Programierer muss höllich auf Übergabeparameter achten! Programmiersprache schützt vor Dummheit nicht.

    typedef struct 
    {
      char Name[512];
      char Nachname[512];
    } tPerson;
    
    void f(tPerson s);
    


  • Bitte ein Bit schrieb:

    typedef struct 
    {
      char Name[512];
      char Nachname[512];
    } tPerson;
    
    void f(tPerson s);
    

    Ja, es gibt natürlich schlechten C-Code.

    Mindestens

    typedef struct tPerson
    {
      char Name[512];
      char Nachname[512];
    } tPerson;
    
    void f(tPerson s);
    

    besser

    typedef struct tPerson
    {
      const char *Name;
      const char *Nachname;
    } tPerson;
    

    wenn Lokalität wichtig ist (und diese Art Optimierung habe ich in C++ noch nie gesehen)

    typedef struct tPerson {
      size_t name_size, nachname_size;
      char data[];
    } tPerson;
    tPerson *person_neu(benutzerfreundlicherString vorname, benutzerfreundlicherString nachname)
    { tPerson *p = malloc(sizeof(tPerson) + vorname.size + nachname.size);
      p->name_size = vorname.size;
      p->nachname_size = nachname.size;
      strcpy(vorname.inhalt, p.data);
      strcpy(nachname.inhalt, p.data + vorname.size);
      return p;
    }
    void person_gib_frei(tPerson *p) { free(p); }
    const char *person_vorname(tPerson *p) { return p->data; }
    const char *person_nachname(tPerson *p) { return p->data + p->vorname_size; }
    


  • wenn Lokalität wichtig ist (und diese Art Optimierung habe ich in C++ noch nie gesehen)

    Ich habe sowas schon of in C++ geschrieben, wobei deine Loesung umstaendlich ist. Du kannst auch einfach zwei char* haben und ein Array mit den beiden Namen getrennt durch ein '\0', dann koennen sie als normale C-Strings behandelt werden, gleich out-of-the-box. Darueber hinaus gibt es mehr Moeglichkeiten ueber placement new oder Allokatoren.

    C++-Programmierer muss höllisch
    

    Ein C Programmierer auch, ein Chirurge auch, ein Physiker auch, ... Das Problem: Wieviel kann der Kompiler mir davon abnehmen? Das ist bei idiomatischem C++ (man kann in C++ auch C programmieren) wesentlich mehr als in C.

    @objdump: Diese Antwort ist nicht fuer dich, aber fuer alle Unvoreingenommenen.



  • C++ lassen sich sehr schöne Dinge mit eigenen Allokatoren lösen. Da bekommt man zb. SSO gratis und solche Lokalitäts-Optimierungen sind auch gut machbar.



  • Kleine Frage am Rand:
    Was versteht man unter Lokalität?

    typedef struct tPerson {
      size_t name_size, nachname_size;
      char data[];  
    } tPerson;
    tPerson *person_neu(benutzerfreundlicherString vorname, benutzerfreundlicherString nachname)
    { tPerson *p = malloc(sizeof(tPerson) + vorname.size + nachname.size);
      // Warum prüfst du hier nicht darauf dass p != NULL ist ?
      p->name_size = vorname.size;
      p->nachname_size = nachname.size;
      // Wer garantiert mir dass vorname und nachname initialisiert sind ?
      strcpy(vorname.inhalt, p.data); // Du kopierst hier p.data nach vorname.inhalt!
      strcpy(nachname.inhalt, p.data + vorname.size); // Du kopierst hier p.data nach vorname.inhalt!
      return p;
    }
    
    // Die Funktion person_neu() erfordert Disziplin. Denn wer ruft person_gib_frei() auf? Und wie?
    void person_gib_frei(tPerson *p) { free(p); }}
    

    Siehst du, auch du hast nach Strich und Faden dein Code verbuggt.

    Ich bin mal gemein. Ich spiele mal Dau!

    benutzerfreundlicherString v;
    benutzerfreundlicherString n;
    tPerson* P;
    tPerson* P2;
    
    v.inhalt = malloc(256);
    strcpy(v.inhalt, "Tom")
    P = person_neu(v, n);
    
    *P2 = P;
    person_gib_frei(&P);
    printf(person_vorname(&P2));
    

    Du arbeitest viel mit Zeigern.



  • objdump schrieb:

    void f(std::string s); // string wird kopiert, ein C++-Programmierer muss höllisch 
                            // aupassen das nicht unabsichtlich hinzuschreiben
    void f(std::string const& s); // indirektion size, doppelte indirektion inhalt
    
    void f(benutzerfreundlicherString *s); // einfache indirektion string+inhalt, nur 1 Pointer parameter
    void f(benutzerfreundlicherString2 s); // nur indirektion für inhalt
    

    Danke für die guten Beispiele. Ein Beispiel von Dir wurde ja schon kommentiert und auf Fehler untersucht. Damit konnten wir beweisen, dass man bei C höllisch aufpassen muss.

    Bei C++ muss man höllisch aufpassen, dass bei der Parameterübergabe der std::string nicht kopiert wird? Wenn man da nicht aufpasst und by value übergibt, dann läuft das Programm nicht mit der optimalen Performance.

    Bei C muss man wohl nur ein bisschen aufpassen. Pufferüberläufe können mal passieren, aber wenn man ein bisschen aufpasst, dann geht das schon. Wenn man da nicht aufpasst, dann stürzt das Programm ab.

    Ich persönlich finde ein Programm, welches nicht mit optimaler Performance arbeitet besser, als ein Programm, welches hin und wieder mal abstürzt.

    Auch muss man bei C ein wenig aufpassen, dass man beispielsweise das "person_gib_frei" geeignet aufruft. Und wenn man die Person kopiert hat, dass man die richtige Kopie und nur die eine frei gibt. Wenn man das nicht tut, dann läuft der Speicher voll. Auch kein gutes Verhalten.

    Da ist mir ein Programm, welches nicht mit optimaler Performance arbeitet doch lieber.



  • @Ethon: Zeig mir mal wie ein eigener Allokator aussieht.
    @Knivil: Du kriegst aber die Stringlänge nicht in konstanter Zeit raus.

    Bitte ein Bit schrieb:

    Ich spiele mal Dau!

    Falscher Ansatz, wenn ich Dau spiele, ist C++ auch nicht sicher.

    C ist keine Sprache für Daus, die sollen auf C++ wechseln. Dass NULL hier als Parameter sinnlos ist, dürfte selbsterklärend sein (spätestens nach dem nächsten Segfault, der unmittelbar auftritt) und dass ich die Parameter für strcpy vertauscht habe, meldet mir mein Compiler. Zeigerfehler, die auch mir passieren können, findet valgrind im nächsten Test.

    tntnet schrieb:

    Ich persönlich finde ein Programm, welches nicht mit optimaler Performance arbeitet besser, als ein Programm, welches hin und wieder mal abstürzt.

    Abstürze und UB sind kein so schlimmes Problem, dafür gibt es Tests.

    Einigen wir uns darauf: C++ arbeitet schnell mal nicht mit optimaler Performance, erleichtert aber unter gewissen Umständen die Entwicklung. C ist schwieriger, man hat aber guten einen Überblick und eine gute Kontrolle darüber, was passiert.


  • Mod

    Bezüglich der Performance der Stringübergabe haben übrigens std::move und Link Time Optimierung angerufen und wollten sich mal vorstellen, dass sie seit einiger Zeit hier in der Gegend wohnen. Die LTO behauptet übrigens, sich auch mit C auszukennen.
    Ich habe hier auch noch eine Postkarte von einer gewissen Copy on write Optimierung, auf der ganz viel zu dem Thema steht. Die Karte scheint aber schon etwas älter zu sein, ich weiß nicht, ob die noch aktuell ist.
    🤡



  • SeppJ schrieb:

    Bezüglich der Performance der Stringübergabe haben übrigens std::move und Link Time Optimierung angerufen und wollten sich mal vorstellen, dass sie seit einiger Zeit hier in der Gegend wohnen. Die LTO behauptet übrigens, sich auch mit C auszukennen.

    Ja, manche Probleme von C++ lösen sich durch höchstkomplexe Optimierungen moderner Compiler. Entsprechend lang dauert auch die Compilezeit. Aber wie viel Zeit ist zwischen dem Kopierkonstruktor und move/LTO vergangen? Ich würde sagen einige.

    Andere Problem kann der C++ aber nicht lösen, eben eine schöne Anordnung des Speichers. Zeig mir mal, wie du ein Array in einer C++-Klasse einbettest, also benutzerfreundlicherString implementieren würdest.

    Angenommen, ein Array von Strings soll umgedreht werden. Ein benutzerfreundlicherString -Array braucht dazu n/2 Pointer-swaps. Ein vector<string> dagegen 3 mal mehr.

    SeppJ schrieb:

    Ich habe hier auch noch eine Postkarte von einer gewissen Copy on write Optimierung, auf der ganz viel zu dem Thema steht. Die Karte scheint aber schon etwas älter zu sein, ich weiß nicht, ob die noch aktuell ist.
    🤡

    COW kann auch nur C++-ern in den Sinn kommen 🙄



  • Es wird objdump überraschen, aber durch Mikrooptimierung bekommt keine Anwendung brutale Performance, sondern dadurch, daß die Entwickler schlaue Algorithmen und Datenstrukturen verwenden, und was am allerwichtigsten ist, die Übersicht behalten.



  • @objdump

    Falscher Ansatz, wenn ich Dau spiele, ist C++ auch nicht sicher.

    Falsch. Und überhaupt komplette falsche Denkweise. Ich will nicht jemanden ankotzen sondern eine Funktion weniger fehleranfällig machen. Da ist mir so ein DAU Ansatz manchmal recht lieb. Man programmiert auch dass ein anderer Benutzer Code XYZ benutzen kann und dieser nicht unbeabsichtigt falsch benutzt oder wenn nur schwer falsch benutzen kann!

    C ist keine Sprache für Daus, die sollen auf C++ wechseln.

    Lass mich raten: C ist eine Sprache für Profis und sollte nur von Profis verwendet werden.

    Dass NULL hier als Parameter sinnlos ist, dürfte selbsterklärend sein (spätestens nach dem nächsten Segfault, der unmittelbar auftritt)

    Erklär das mal einem Kunden. Ähh Entschuldigung, wir haben nicht genug getestet und haben deswegen noch ein Segfault. Sie bekommen in 5 Minuten ihr Bugfix zugesendet...

    und dass ich die Parameter für strcpy vertauscht habe, meldet mir mein Compiler.

    Das bezeifele ich. Deine Eingabeparameter sind nicht const, also darf ich etwas problemlos andere Daten drüberkopieren. Abhängig vom Compiler dürfte er entweder direkt abstürzen oder auch Schrott drüberkopieren. Ein strlen((char*) malloc(8)); geht bei mir problemlos.

    Zeigerfehler, die auch mir passieren können, findet valgrind im nächsten Test.

    Auch eine Art des Programmieren. Scheiß auf evt. Fehler. Wozu gibts valgrind. Geil. 😉

    Volkard schrieb:

    Es wird objdump überraschen, aber durch Mikrooptimierung bekommt keine Anwendung brutale Performance, sondern dadurch, daß die Entwickler schlaue Algorithmen und Datenstrukturen verwenden, und was am allerwichtigsten ist, die Übersicht behalten.

    Wie ineffizient. Tss 😃

    Bedeutet nicht Effiziens die sorgsame Aufzucht und Pflege von vermeidbaren Fehlern unter dem Deckmantel ein paar Takte sparen zu können?



  • gähn
    🙄



  • Es wird volkard überraschen, aber als ich das letzte mal C++ programmiert habe, habe ich immer brav const& Schnittstellen gemacht, bis ich irgendwann gemerkt habe, dass in-place-ändern doch besser wäre. In der Folge musste ich immer alles kopieren, was die Performance massiv beeinträchtigt hat. Seither bleibe ich in C bei dummen structs und klugen Algorithmen.

    C ist eine Sprache für Profis und sollte nur von Profis verwendet werden.

    👍



  • C ist eine Sprache für Profis und sollte nur von Profis verwendet werden.

    full ack! 👍



  • objdump schrieb:

    Es wird volkard überraschen, aber als ich das letzte mal C++ programmiert habe, habe ich immer brav const& Schnittstellen gemacht, bis ich irgendwann gemerkt habe, dass in-place-ändern doch besser wäre. In der Folge musste ich immer alles kopieren, was die Performance massiv beeinträchtigt hat. Seither bleibe ich in C bei dummen structs und klugen Algorithmen.

    Vielleicht haste nur die falschen C++-Bücher in der Hand gehabt. Wenn die Dir einen Stil einreden wollten, der bremst, ist klar, daß Du Dich da unwohl fühlst.



  • mhh, hätte ich gewusst, dass die ganze diskussion SO ausartet, hätte ich den thread nicht angefangen 🙄

    es geht hier NICHT um "c vs c++" sondern darum, welche funktion schneller ist.

    die antwort ist, sofern ich die beiträge, die meine frage beantwortet haben, richtig verstanden habe, strcmp.


  • Mod

    threadstarter schrieb:

    es geht hier NICHT um "c vs c++" sondern darum, welche funktion schneller ist.

    Um dieses Thema geht es in diesem Subforum immer 😃 . Warte nur, bis die ersten Java-Programmierer sich in die Diskussion einmischen…



  • SeppJ schrieb:

    threadstarter schrieb:

    es geht hier NICHT um "c vs c++" sondern darum, welche funktion schneller ist.

    Um dieses Thema geht es in diesem Subforum immer 😃 . Warte nur, bis die ersten Java-Programmierer sich in die Diskussion einmischen…

    Und wenn volkard aktiv ist irgendwie viel öfters. Eigentlich hatten wir doch schon länger keinen solchen Thread mehr.


Anmelden zum Antworten