2

It seems Console.WriteLine(...) is really slow in C#.

Here's the code I tested.

var iterations = 5000;
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < iterations; i++) 
    Console.WriteLine("adsdsaddhfuihdsuifhdsufudshfoadfdshoadsuoadsuioadsihfuidh");
watch.Stop();
double msPerOp = 1.0 * watch.ElapsedMilliseconds / iterations;
Console.WriteLine("{0} ms/op", msPerOp);

In my laptop, it prints 5.731 ms/op.

Why is it so slow?

As far as I know, printing to console in other languages is not this slow. For example, in Go, fmt.Println(...) with same string only takes 416275 ns/op (= 0.416275 ms/op) in my laptop.

(tested with go test -bench .)

Why is Console.WriteLine(...) so slow in c#? Is there any alternative I can use which has a performance similar with Go's fmt.Println(...)?

EDIT) The reason I need fast Console.WriteLine(...) is following.

My application continuously receives a lots of real time data (20~80 data/sec) by windows message loop, and I want to simply print the data every time I receive with Console.WriteLine. I should print it fast because if not, real time data gets delayed.

However, it seems Console.WriteLine(...) takes 5~10ms (for long string).. and this is too slow for real time data processing.

asqdf
  • 289
  • 2
  • 9
  • 1
    The Windows Console itself is slow. – Jonathon Reinhart Mar 08 '17 at 12:02
  • @JonathonReinhart However Golang's `fmt.Println` in windows console only takes 416.275 us, while C#'s `Console.WriteLine` takes 5.731ms. – asqdf Mar 08 '17 at 12:04
  • 3
    What exactly are you trying to achieve? – walther Mar 08 '17 at 12:07
  • 1
    Why do you need such performance - which is well beyond human capability of reading. – PaulF Mar 08 '17 at 12:08
  • yep, the cmd is slow. I've seen it while restoring some DB dumps... It was printing every record... When visible it was taking about 20 minutes, when minimized about 3-4 minutes – mihail Mar 08 '17 at 12:15
  • @walther I added why I need such performance in the question. – asqdf Mar 08 '17 at 12:17
  • @PaulF I added why I need such performance in the question. – asqdf Mar 08 '17 at 12:17
  • You could try to capture the output to a buffer rather than the console and periodically flush the buffer to the console or even a log file. – Dave Becker Mar 08 '17 at 12:18
  • 1
    Possible duplicate of [Console.WriteLine slow](http://stackoverflow.com/questions/5272177/console-writeline-slow) – PaulF Mar 08 '17 at 12:22
  • @DaveBecker Well.. my purpose of printing to the console is to monitor real time data. So it's necessary to flush it every time the real time data arrives. – asqdf Mar 08 '17 at 12:23
  • I have around 0,056ms/op with your sample and its not getting any better when I directly DllImport [`WriteConsole`](https://msdn.microsoft.com/en-us/library/windows/desktop/ms687401(v=vs.85).aspx) into the program and use this instead... – grek40 Mar 08 '17 at 12:28
  • 1
    If you want to monitor some real-time data, you won't read so fast anyway. What you need to do is to buffer your input and print out only the average value for the given time period (e.g. 500ms). There's really no point in dumping so many rows to the console. – walther Mar 08 '17 at 12:33
  • Also see this : http://stackoverflow.com/questions/3670057/does-console-writeline-block Particularly the last answer. – PaulF Mar 08 '17 at 12:33
  • @grek40 Can't believe it.. so this is maybe hardware problem – asqdf Mar 08 '17 at 12:39
  • If you read the last link I gave you will see that it is an issue with Console.WriteLine waiting for the string to be written & the console to be redrawn - so will be affected be the speed of your hardware. There are solutions given in that link. – PaulF Mar 08 '17 at 12:41
  • @walther Umm.. I just wanted to print the data fast every time it arrives because it just worked for my equivalent golang application.. Anyway, thanks for your comment. – asqdf Mar 08 '17 at 12:42
  • @PaulF Thanks for the comment. That's really important information for me. – asqdf Mar 08 '17 at 12:44
  • Just take the earliest data and print it once a second. – FCin Mar 08 '17 at 12:48

1 Answers1

3

I don't know whether your laptop is really that much slower, but for me (Release build, running on Windows 7 x64 workstation) your testing code output is 0.056 ms/op.

I tried the WinAPI WriteConsole function as comparison and it didn't improve performance at all (0.0586 ms/op).

You can compare for yourself, whether you get different results.

public class Program
{
    public enum StandardHandleType
    {
        STD_INPUT_HANDLE = -10,
        STD_OUTPUT_HANDLE = -11,
        STD_ERROR_HANDLE = -12
    }

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    public static extern IntPtr GetStdHandle(StandardHandleType handleType);

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    public static extern bool WriteConsole(
        IntPtr hConsoleOutput,
        string lpBuffer,
        int nNumberOfCharsToWrite,
        ref int lpNumberOfCharsWritten,
        IntPtr lpReserved
        );

    static void Main()
    {
        IntPtr console = GetStdHandle(StandardHandleType.STD_OUTPUT_HANDLE);

        int written = 0;

        var iterations = 5000;
        var watch = new Stopwatch();
        watch.Start();
        string s = "adsdsaddhfuihdsuifhdsufudshfoadfdshoadsuoadsuioadsihfuidh\n";
        for (int i = 0; i < iterations; i++)
            //Console.WriteLine("adsdsaddhfuihdsuifhdsufudshfoadfdshoadsuoadsuioadsihfuidh");
            WriteConsole(console, s, s.Length, ref written, IntPtr.Zero);
        watch.Stop();
        double msPerOp = 1.0 * watch.ElapsedMilliseconds / iterations;
        Console.WriteLine("{0} ms/op", msPerOp);
        Console.ReadKey();
    }
}
grek40
  • 13,113
  • 1
  • 24
  • 50
  • I tried your code, and both of `WriteConsole` and `Console.WriteLine` took around 6ms/op. So this is probably my hardware's problem. (.NET 4.6, Release Build, Windows 10, Mac Pro Retina 2013 `15..) – asqdf Mar 08 '17 at 12:49
  • 1
    @asqdf well consider yourself lucky. Imagine the damage if you had started developing with good performance and failing later in production ;) Now you can focus on more reliable output methods. – grek40 Mar 08 '17 at 13:06