Trennlinie ausgeben



  • earli: Du meinst wohl "am langsamsten".



  • earli schrieb:

    Ich würde auch die Schleife mit putchar() empfehlen.

    Am schnellsten ist wahrscheinlich folgendes:

    char *s = malloc(n + 1);
    memset(s,'-', n-1);
    s[n] = '\0';
    printf(s);
    

    Da kann ich aber auch bei dem hier bleiben

    for (i=0; i<10; i++)
         printf("-");
    

    Geht schneller zu tippen und ist vermutlich auch viel schneller, von der Übersichtlichkeit ganz zu schweigen...



  • gast007 schrieb:

    Da kann ich aber auch bei dem hier bleiben

    Ja, aber mit putchar.

    for (i=0; i<10; i++)
         putchar('-');
    

    Das printf wertet den ersten Parameter als Formatstring aus. Das fällt bei putchar alles weg.



  • gibt's da auch eine Entsprechung zu fprintf?



  • Klar: fputc()
    oder putc()

    Aber putc() kann auch ein Makro (mit evtl. Nebenefeckten) sein.



  • gast007 schrieb:

    earli schrieb:

    Ich würde auch die Schleife mit putchar() empfehlen.

    Am schnellsten ist wahrscheinlich folgendes:

    char *s = malloc(n + 1);
    memset(s,'-', n-1);
    s[n] = '\0';
    printf(s);
    

    Da kann ich aber auch bei dem hier bleiben

    for (i=0; i<10; i++)
         printf("-");
    

    Geht schneller zu tippen und ist vermutlich auch viel schneller, von der Übersichtlichkeit ganz zu schweigen...

    printf ist total teuer, das rufst du da 10 mal. Ich mach nur einen Aufruf memset und einen Aufruf printf.

    Verbesserung meiner Variante:

    dynamische Länge:

    char *s = malloc(n + 1);
    memset(s,'-', n-1);
    s[n] = '\0';
    puts(s);
    

    feste Länge:

    puts("------------------------");
    

    das sollten die schnellsten sein

    PS:
    Mach niemals eigene Schleifen für Dinge, für die es schon Funktionen in der libc gibt. Egal, wie du es machst, du kannst davon ausgehen, dass die libc-Programmierer es besser gemacht haben.



  • earli schrieb:

    printf ist total teuer, das rufst du da 10 mal.

    Stimmt, die Lösung besteht darin, printf durch putchar zu ersetzen. Deine Lösung dagegen ist für die Tonne.

    Ich mach nur einen Aufruf memset und einen Aufruf printf.

    Und einen von malloc.



  • Bashar schrieb:

    earli schrieb:

    printf ist total teuer, das rufst du da 10 mal.

    Stimmt, die Lösung besteht darin, printf durch putchar zu ersetzen. Deine Lösung dagegen ist für die Tonne.

    Ich mach nur einen Aufruf memset und einen Aufruf printf.

    Und einen von malloc.

    Das malloc könnte wirklich was ausmachen. Ich mess mal aus.

    putc zu wiederholen ist aber auf jeden Fall langsamer als ein puts. printf war wirklich nicht so gut, deshalb die verbesserte Version.



  • Das macht aber nicht das Gleiche, da puts noch ein '\n' dranhängt.



  • earli schrieb:

    putc zu wiederholen ist aber auf jeden Fall langsamer als ein puts.

    Nachgemessen? Kann eigentlich nicht viel ausmachen, da putc üblicherweise ein Makro ist, das nicht viel mehr tut als das Zeichen in den Puffer zu kopieren und zu prüfen, ob geflusht werden muss.



  • Sollte man sich wirklich Gedanken darüber machen, Ausgaben auf der Konsole optimieren zu wollen?
    Bspw. unter Windows sind diese derart langsam, dass Optimierungsversuche imho schlichtweg Zeitverschwendung sind.

    void println(unsigned int n)
    {
      while(n--) putc('-');
    }
    

    Ich wäre überrascht, wenn Obiges messbar langsamer wäre und die zeitliche Differenz es hergeben würde, sich noch weitere Gedanken darüber zu machen.



  • Bashar schrieb:

    earli schrieb:

    putc zu wiederholen ist aber auf jeden Fall langsamer als ein puts.

    Nachgemessen? Kann eigentlich nicht viel ausmachen, da putc üblicherweise ein Makro ist, das nicht viel mehr tut als das Zeichen in den Puffer zu kopieren und zu prüfen, ob geflusht werden muss.

    Also bei mir braucht (bei 1 Mio. Wiederholungen) die Variante putc-in-for-Schleife 150 ms und malloc-memset-puts braucht 130 ms.

    (Ubuntu Linux, also eglibc, 64 Bit).



  • DirkB schrieb:

    Das macht aber nicht das Gleiche, da puts noch ein '\n' dranhängt.

    Dann halt fputs(s, stdout);



  • putc in der GNU libc:

    int
    _IO_putc (c, fp)
         int c;
         _IO_FILE *fp;
    {
      int result;
      CHECK_FILE (fp, EOF);
      _IO_acquire_lock (fp);
      result = _IO_putc_unlocked (c, fp);
      _IO_release_lock (fp);
      return result;
    }
    INTDEF(_IO_putc)
    

    [...]

    weak_alias (_IO_putc, putc)
    

    siehe glibc/libio/putc.c



  • Und jetzt noch puts.c bitte.



  • DirkB schrieb:

    Und jetzt noch puts.c bitte.

    puts() wird ne Schleife machen, aber printf() macht viel mehr. printf() weiß ja nicht einmal, wie viele Argumente auf dem Stack liegen.



  • Das ist übel. OK, du hast gewonnen. Der Break-Even ist bei mir ungefähr bei 25 Zeichen, ab da ist die puts-Variante schneller, trotz malloc/free.
    In der Praxis dürfte malloc aber nicht so zahm sein. Hier kann es ja praktisch sofort den erstbesten freien Block anschneiden und belegt auch immer denselben Block. In einem schon etwas verwohnten Heap sähe das vermutlich anders aus.



  • Jo, malloc() kostet fast nichts, wenn die Speicherverwaltung schon die Page hat. Dann kriegt man einfach einen Pointer und wird in eine Reservierungstabelle eingetragen.


Anmelden zum Antworten