Forum: PC-Programmierung Warum ist diese Prozedur schneller als system("cls")


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bartosz B. (bartosz)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe mir vor längerer Zeit mal diese Prozedur kopiert. Sie ist sehr 
schnell, schneller als system("cls").
1.) Woran liegt das?
2.) Habt ihr Verbesserungsvorschläge?

Ich nutze Windows 8.1 64 Bit; Visual Studio 2019 Professional

[c]
void ueberschreiben()
{
  // Get the Win32 handle representing standard output.
  // This generally only has to be done once, so we make it static.
  static const HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

  CONSOLE_SCREEN_BUFFER_INFO csbi;
  COORD topLeft = { 0, 0 };

  // std::cout uses a buffer to batch writes to the underlying console.
  // We need to flush that to the console because we're circumventing
  // std::cout entirely; after we clear the console, we don't want
  // stale buffered text to randomly be written out.
  std::cout.flush();

  // Figure out the current width and height of the console window
  if (!GetConsoleScreenBufferInfo(hOut, &csbi))
  {
    // TODO: Handle failure!
    abort();
  }
  DWORD length = csbi.dwSize.X * csbi.dwSize.Y;

  DWORD written;

  // Flood-fill the console with spaces to clear it
  FillConsoleOutputCharacter(hOut, TEXT(' '), length, topLeft, 
&written);

  // Reset the attributes of every character to the default.
  // This clears all background colour formatting, if any.
  FillConsoleOutputAttribute(hOut, csbi.wAttributes, length, topLeft, 
&written);

  // Move the cursor back to the top left for the next sequence of 
writes
  SetConsoleCursorPosition(hOut, topLeft);
}
[\c]

von Programmierer (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Bartosz B. schrieb:
> system("cls")

Ist grundsätzlich schon mal langsam, da das Starten neuer Prozesse, wie 
eben z.B. cls, insbesondere auch unter Windows, ziemlich langsam ist. 
Die direkten Aufrufe an das Windows API vermeiden diesen ganzen 
Overhead.

von Εrnst B. (ernst)


Bewertung
1 lesenswert
nicht lesenswert
Programmierer schrieb:
> Ist grundsätzlich schon mal langsam,

Lustigerweise Schlägt das Microsoft selber in der Console-Doku vor, ohne 
Hinweis auf die grottige Perfomance…

https://docs.microsoft.com/en-us/windows/console/clearing-the-screen

von DPA (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Also, unter Linux ist das viel einfacher. Dort nimmt man einfach 
terminfo für sowas. Das funktioniert dann, anders als der Windows Mist, 
auch mit jeder art Terminal, ob Terminalemulator, Seriell, über SSH, 
etc. geht alles.
#include <term.h>
int main(){
  setupterm(0, 1, 0); // Initialise stuff
  putp(tigetstr("clear")); // Get escape sequence for clearing the screen and print it.
}
$ gcc clear.c -o clear -ltinfo
$ ./clear

von DPA (Gast)


Bewertung
2 lesenswert
nicht lesenswert
Hier noch die wichtigsten Terminfo capabilities: 
http://man7.org/linux/man-pages/man5/terminfo.5.html

Unter Windows müsste das über curses theoretisch auch einsetzbar sein.

von Bauform B. (bauformb)


Bewertung
2 lesenswert
nicht lesenswert
system() ist ungefähr das langsamste was es gibt. Damit wird ja erstmal 
eine shell gestartet und die startet dann cls. curses hat den Vorteil, 
dass es einfach ein FormFeed ausgibt, wenn man einen Nadeldrucker 
verwendet. Aber dann wieder, wer benutzt schon noch Ausgabegeräte, die 
"\033[2J" nicht  verstehen?

von foobar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wir leben in einer Zeit, wo die Leute, statt den Lichschalter zu 
betätigen, ein "Alexa, schalt das Licht ein" rufen ;-)

von Bartosz B. (bartosz)


Bewertung
0 lesenswert
nicht lesenswert
Bauform B. schrieb:
> system() ist ungefähr das langsamste was es gibt. Damit wird ja erstmal
> eine shell gestartet und die startet dann cls.
Ok, das wusste ich nicht.

>curses hat den Vorteil,
> dass es einfach ein FormFeed ausgibt, wenn man einen Nadeldrucker
> verwendet. Aber dann wieder, wer benutzt schon noch Ausgabegeräte, die
> "\033[2J" nicht  verstehen?
Das versteh ich jetzt nicht. Kannst du das bitte kurz erklären?

von foobar (Gast)


Bewertung
2 lesenswert
nicht lesenswert
>> Aber dann wieder, wer benutzt schon noch Ausgabegeräte, die
>> "\033[2J" nicht  verstehen?
>
> Das versteh ich jetzt nicht. Kannst du das bitte kurz erklären?

Er will sagen, dass ein
#include <stdio.h>

int main(int argc, char **atgv)
{
    fputs("\033[2J", stdout);   // besser "\033[H\033[2J"
    return 0;
}
auf vielen Systemen eine gute Methode ist, den Bildschirm zu löschen. 
Stichwort "ansi escape sequenzen"

von Bartosz B. (bartosz)


Bewertung
0 lesenswert
nicht lesenswert
Danke

von DPA (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Es gibt diverse arten von Terminals. Das kann ein Drucker, ein echtes 
physisches Terminal, eine Schreibmaschine, ein Terminal Emulator (das 
ist Console technisch gesehen), und vieles mehr sein. So ziemlich alle 
diese interpretieren Escape Sequenzen, das sind Abfolgen von 
Steuerzeichen, die für diese Geräte eine besondere Bedeutung haben. 
Diese können einfach zusammen mit dem auszugebenden Text ausgegeben 
werden, denn im Grunde sind es ja auch nur ein paar Bytes / Zeichen. 
Verschiedene Ausgabegeräte unterstützen verschiedene Escapesequenzen, 
die Terminfo Datenbank enthält die Information / Abstraktion, bei 
welchem gerät, für welche Aktion (Screen/Zeile leeren, Farbe setzen, 
Curser setzen, etc.) welche Escapesequenz gesendet werden muss, sofern 
es bei dem Gerät eine dafür gibt. Newline NL (\n) Carriage Return CR 
(\r), sind eigentlich auch eine art Steuerzeichen/Escapesequenzen. Die 
meisten heutigen terminal Emulatoren sind Kompatibel zu xterm, welches 
kompatibel zu vt220 ist, welches kompatibel zu vt100 ist, usw.

Die Windows Console ist noch ein Spezialfall in dem sinne, dass diese 
nicht nur sehr wenige (nämlich ANSI) Escapesequenzen unterstützt, 
sondern diese auch nur optional, wenn aktiviert. Statdessen ist es stark 
in die WinAPI integriert, weil MS mal wieder alles anders als alle 
anderen machen muss, damit Programme auch schön Windows spezifisch 
werden. Hat sich dort natürlich langfristig nicht durchgesetzt.

Ich würde empfehlen, einen anderen Terminal Emulator als die Windows 
Console zu verwenden. Diese ist der langsamste Terminal Emulator, den 
ich kenne, ganz egal, wie man es auch ansteuern mag.

von Bartosz B. (bartosz)


Bewertung
0 lesenswert
nicht lesenswert
Wow, vielen Dank für die ausführliche Antwort!

DPA schrieb:


> Ich würde empfehlen, einen anderen Terminal Emulator als die Windows
> Console zu verwenden. Diese ist der langsamste Terminal Emulator, den
> ich kenne, ganz egal, wie man es auch ansteuern mag.

Ja, das ist so ein bisschen meine Baustelle aktuell. Nachdem ich in der 
Uni einen Crashkurs in C und VB bekommen habe, programmier ich nur in 
meiner Freizeit. Ich bin weiter als der Anfänger in der Uni, aber was C 
Projekte angeht, muss ich immer auf ein Konsolenprojekt zurückgreifen. 
Daher weiche ich meist auf ein VB.NET WinForms Projekt aus, mit 
Text-Entry-Boxen und Pictureboxen etc (und damit kann ich richtig gut 
programmieren!!). Ich komme in C aktuel nicht weiter... Ich hab hier vor 
Kurzem einen Thread gesehen, in dem es darum ging, eine möglichst 
ansehnliche GUI in C zu erzeugen. Das habe ich überhaupt nicht 
verstanden, was ihr da besprochen habt. :( ich werde nachher mal so 
einen Thread machen..

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bartosz B. schrieb:
> Ich hab hier vor Kurzem einen Thread gesehen, in dem es darum ging, eine
> möglichst ansehnliche GUI in C zu erzeugen. Das habe ich überhaupt nicht
> verstanden, was ihr da besprochen habt. :( ich werde nachher mal so
> einen Thread machen..

Die Frage ist, warum man sowas in C macht. C ist eine sehr primitive 
Sprache mit vielen Fallstricken, in der man alles von Hand machen muss. 
Grafische Programme für den PC kann man viel besser in C#, Java, Python, 
VB... schreiben. Auf C++ greift man zurück wenn man besondere 
Performance Ansprüche hat, ist immer noch besser als C. C ist nur 
sinnvoll wenn man mit bestimmten Low-Level Interfaces oder FFI's 
hantieren muss. Aber das ist sowieso nix für Anfänger.

Bartosz B. schrieb:
> Nachdem ich in der Uni einen Crashkurs in C und VB bekommen habe,

Es ist sowieso ziemlicher Blödsinn, dass die Unis den Leuten C 
eintrichtern. In so einem Crashkurs kann man da sowieso nur ein 
gefährliches Viertelwissen aufbauen. Mit den anderen genannten Sprachen 
kann man viel schneller und einfacher Ergebnisse erzielen, was dann 
natürlich auch mehr motiviert. Viel wichtiger als die Sprache selbst ist 
sowieso das Wissen um gute Programmstruktur/Architektur, welche zu 
erlernen aber keine Zeit mehr ist wenn man sich nur mit den Details und 
Fußangeln von C rumplagt. Besonders pikant ist die Tatsache, dass an den 
Unis oft sogar fehlerhaftes C gelehrt wird, weil die Profs es selbst 
nicht können, aber zu faul sind über den Tellerrand zu schauen.

von Karl (Gast)


Bewertung
0 lesenswert
nicht lesenswert
foobar schrieb:
> Wir leben in einer Zeit, wo die Leute, statt den Lichschalter zu
> betätigen, ein "Alexa, schalt das Licht ein" rufen ;-)

Richtig. Aufstehen, zum Schalter gehen, Schalter betätigen, zurück zum 
Sessel gehen, hinsetzen. Das ist sowas von Vorgestern. "Alexa, Licht an" 
ist einfacher und schneller.

von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
Karl schrieb:
> foobar schrieb:
>> Wir leben in einer Zeit, wo die Leute, statt den Lichschalter zu
>> betätigen, ein "Alexa, schalt das Licht ein" rufen ;-)
>
> Richtig. Aufstehen, zum Schalter gehen, Schalter betätigen, zurück zum
> Sessel gehen, hinsetzen. Das ist sowas von Vorgestern. "Alexa, Licht an"
> ist einfacher und schneller.

Zudem verschwendet man mit der non-Alexa-Variariante auch noch jede 
Menge von den aufwendig mittels Chips&Cola "geschürften" Kalorien.

von Bartosz B. (bartosz)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> Bartosz B. schrieb:
>> Ich hab hier vor Kurzem einen Thread gesehen, in dem es darum ging, eine
>> möglichst ansehnliche GUI in C zu erzeugen. Das habe ich überhaupt nicht
>> verstanden, was ihr da besprochen habt. :( ich werde nachher mal so
>> einen Thread machen..
>
> Die Frage ist, warum man sowas in C macht. C ist eine sehr primitive
> Sprache mit vielen Fallstricken, in der man alles von Hand machen muss.
> Grafische Programme für den PC kann man viel besser in C#, Java, Python,
> VB... schreiben. Auf C++ greift man zurück wenn man besondere
> Performance Ansprüche hat, ist immer noch besser als C. C ist nur
> sinnvoll wenn man mit bestimmten Low-Level Interfaces oder FFI's
> hantieren muss. Aber das ist sowieso nix für Anfänger.

OK, dann werde ich, was Grafik anbelangt, bei VB bleiben.

> Bartosz B. schrieb:
>> Nachdem ich in der Uni einen Crashkurs in C und VB bekommen habe,
>

> Mit den anderen genannten Sprachen
> kann man viel schneller und einfacher Ergebnisse erzielen, was dann
> natürlich auch mehr motiviert.
Richtig!
>Viel wichtiger als die Sprache selbst ist
> sowieso das Wissen um gute Programmstruktur/Architektur, welche zu
> erlernen aber keine Zeit mehr ist wenn man sich nur mit den Details und
> Fußangeln von C rumplagt. Besonders pikant ist die Tatsache, dass an den
> Unis oft sogar fehlerhaftes C gelehrt wird, weil die Profs es selbst
> nicht können, aber zu faul sind über den Tellerrand zu schauen.

Finde ich auch

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.