2017-01-04 3 views
1

Wurde mein Code Profiling und festgestellt, dass die Art und Weise, wie wir tun, farbige Konsole Text ist sehr teuer (die Mehrheit der Laufzeit).Gibt es eine schnellere Möglichkeit, Konsolenfarben einzustellen?

DateTime dt = DateTime.Now; 

    for (int i = 0; i <= 20000; i++) 
    { 
     ConsoleColor cf = Console.ForegroundColor; 
     ConsoleColor cb = Console.BackgroundColor; 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.BackgroundColor = ConsoleColor.Blue; 
     Console.WriteLine("Hello World"); 
     Console.ForegroundColor = cf; 
     Console.BackgroundColor = cb; 
    } 

    System.Diagnostics.Debug.WriteLine((DateTime.Now - dt).TotalMilliseconds); 

Diese einfache Schleife dauert 2,8 Sekunden, um auf meinem Rechner zu laufen. Wenn ich nur die WriteLine mache, sind es nur 600ms.

Nun bevor ich Troll Antworten bekomme :) fragen, warum ich die Farbe immer wieder einstellen, wenn sein fest einprogrammiert, DIES IST TEST CODE, in dem realen Code, die Vorder- und Hintergrundfarben sind auf ein paar verschiedenen Faktoren berechnet . Dieser Teil ist irrelevant. Dieser Code geht nur davon aus, dass sich die Farbe ändert und speichert somit die Originale, ändert die Farben und ändert sie wieder auf das Original.

Ich habe auch versucht, die native SetConsoleTextAttribute-Methode durch pinvoke seit der Verwendung von ILSpy, es schien wie die Console.xxx-Methoden waren eine Menge extra Mist, aber ich habe etwa die gleichen Timings.

+0

Das Ändern einer Eigenschaft in der Konsole (oder das Ausführen der meisten Aufgaben mit der Konsole) beinhaltet P/Aufrufen des Konsolenprozesses. Es würde Sinn machen, dass dies einen nicht-trivialen Overhead mit sich bringt. – Abion47

+0

@ Abion47 Ich hatte Zeiten, in denen Pinvoke schneller ist als das Aufrufen der C# -Wrapper, weil sie eine Menge Dinge tun, um kugelsicherer zu sein, während man mit dem direkten Pinvoke-Aufruf all das umgehen kann. Die C# -Wrapper sind wahrscheinlich ein paar hundert Zeilen Code :). Scheint so, als ob das Ändern einer Textfarbe in der Konsole trivial sein sollte. – SledgeHammer

+0

Verwenden Sie 'DateTime' nicht für Zeitberechnungen - verwenden Sie' Stoppuhr'. –

Antwort

2

Nicht wirklich. Wie Sie bereits bemerkt haben, interagieren die in Console integrierten Eigenschaften direkt mit SetConsoleTextAttribute, die Möglichkeit, Konsolenausgabeeigenschaften in Windows festzulegen.


Wenn ANSI Farben eine Option sind, die wesentliche Änderungen Logik würden Sie mit Konsole Farben haben arbeiten, ist es ist schneller. Ein minimaler Fall

for (int i = 0; i <= 20000; i++) 
{ 
    Console.WriteLine("\x1b[31m\x1b[44mHello World\x1b[39m\x1b[49m"); 
} 

läuft in etwa 1200 ms auf meinem Rechner, im Vergleich zu etwa 7000 ms mit den Console.xxxColor Eigenschaften.

Sie benötigen eine kompatible Shell. Ansicon funktioniert.


Mit ANSI-Farben können Sie Ihre Ausgabe zusätzlich für noch mehr Zeiteinsparungen chargen. Selbst Reihen von 20 Zeilen hacken die Laufzeit über die Hälfte. * Wenn Sie aus irgendeinem Grund auf die Konsole spammen, könnte das erheblich helfen.

* Auf meiner Maschine.

+0

Ja, ich habe vor ein paar Tagen über die Verwendung von ANSI nachgedacht, aber dann habe ich gelesen, dass die Standardkonsole das nicht unterstützt, also habe ich es nicht einmal versucht. Auf der Heimfahrt heute Abend dachte ich darüber nach, meine eigene Set-Funktion zu schreiben, die den Hintergrund und den Vordergrund in einem einzigen Aufruf erledigen kann (da SetConsoleTextAttribute das kann), aber das hilft nur, wenn der Benutzer beide Farben einstellt. Wahrscheinlich werde ich morgen versuchen, eine native C++ - Konsolenanwendung zu schreiben und zu sehen, wie SetConsoleTextAttribute dort funktioniert ... aber die Tatsache, dass ANSI so viel schneller ist, zeigt, dass irgendwo unnötiger Aufwand entsteht ... – SledgeHammer

+0

Ich habe es in nativem C++ und 20.000 Iterationen benötigten nur 1.24 Sekunden (gegenüber 2,8 in C#). Zum Vergleich: Nur der Druck in C++ benötigte 586ms, was vergleichbar ist mit dem C# -Ausgabewert. Ich habe noch nie gesehen, dass Pin-Invoke so viel Aufwand verursacht. – SledgeHammer

Verwandte Themen