-2

I tested the speed of i.ToString(), i + "", Console.WriteLine(i+"") and Console.WriteLine(i). (i was an int) The results were the following:

i.ToString() (149 ms) was faster than i + "" (202 ms).

But when I used Console.WriteLine Console.WriteLine(i + "") (743 ms) was a lot faster than Console.WriteLine(i) (927 ms, according to TextWriter source Console.WriteLine calls ToString() internally).

Now my question is: Why is i + "" faster in combination with Console.WriteLine()?

Notes:

  1. I used 1,000,000 iterations for the non-console stuff and 1,000 for my console tests.
  2. I use .NET Framework 4.7.1
  3. The code was compiled with Debug configuration in Visual Studio 2017 (version 15.9.4). Release gives similar results.
  4. The project type is console application.
  5. Code is available as a GitHub Gist
Community
  • 1
  • 1
user78403
  • 352
  • 2
  • 11
  • 5
    Before we discuss your results and worry about 50 milliseconds in an undefined benchmark, can you paste your benchmark code, what framework, whether you did this in debug or release. – TheGeneral Feb 02 '19 at 23:29
  • how about `StringBuilder` ? did you tested it? – Zam Feb 02 '19 at 23:29
  • also, is it `WPF - Console App` or "regular" Console App? – Zam Feb 02 '19 at 23:31
  • @MichaelRandall SO refuses to take my code (too much code,not enough text) so i have to find place to put it online first. I'll edit my question to include more information. – user78403 Feb 02 '19 at 23:32
  • 3
    Use a proper bench environment like [BenchmarkDotNet](https://benchmarkdotnet.org/). That said, are you trying to measure both in independent program runs, or are you trying to measure both together in a single program run? –  Feb 02 '19 at 23:38
  • One run at the moment, but I found out about that stuff in independent runs. I 'll test it again in independent code. – user78403 Feb 02 '19 at 23:42
  • Yeah, no. You don't measure what you think you are measuring. Note that `Console.WriteLine(i+"")` in your code gets a head start, since it has the previlege to start printing into an empty console. Later outputs to the console will need to scroll the console window content and manage the console buffer, which will cost time, of course... (how much exactly will depend on several factors) –  Feb 02 '19 at 23:43
  • No, the console isn't empty at that time. This would also only concern one iteration of 1,000. – user78403 Feb 02 '19 at 23:43
  • It is _almost_ empty,... unless your console window and buffer only have space for a couple of lines. It concerns as many iterations as the output doesn't need to scroll yet (as well as hitting the end of the console buffer) –  Feb 02 '19 at 23:44
  • 1
    Looks like there was a `stopwatch.Restart()` missing in my code... It looks completely different now. Both ways are about the same speed now. – user78403 Feb 02 '19 at 23:49
  • New results from independent runs: `Console.WriteLine(i+"")`: 500ms-900ms; `Console.WriteLine(i.ToString())`: 800ms-1300ms. That matches @OndřejKubíček's answer. – user78403 Feb 03 '19 at 00:02
  • @user78403 Can you update these numbers to your question? So the newcomers wouldn't be that scared how slow the .WriteLine() can be? – Ondřej Kubíček Feb 03 '19 at 00:11
  • Hmmm... I think I could do that... But Console.WriteLine() **is** slow! :D – user78403 Feb 03 '19 at 00:15
  • @user78403 Yeah, but what is slow is the TextWriter implementation of .WriteLine(int) :D So it is a lot slower if you use FileStream to write into file. Anyway this behavior is very interesting to me and it was a fun to investigate it. – Ondřej Kubíček Feb 03 '19 at 10:29

1 Answers1

2

When I looked at source code, I saw this:

i + "" = String.Concat(object) which call obj.ToString() There is one more String.Concat(object). So it is slower.

1st way) With Console.WriteLine it is simple:

    public static void WriteLine(String value)
    {
        Out.WriteLine(value);
    }

https://referencesource.microsoft.com/#mscorlib/system/console.cs,5ac7c4fda643413b

Internaly it creates 1 buffer with value + '\r\n' and call .Write(char[], int, int) only once.

2nd way) When you call it with int, it is different.

    public virtual void WriteLine(int value) {
        Write(value);
        WriteLine();
    }

https://referencesource.microsoft.com/#mscorlib/system/console.cs,82d5745bf4a5ecc6

That way it calls Write(char[], int, int) twice. And it can be that slowdown but I can't tell for sure. It is only the hint, where the problem can be.

EDIT:

Additionaly the 2nd way, it calls int.ToString(IFormatProvider) to get string representation of number where is another overhead that can slow it down a little because it can get the instance of that provider every time. https://referencesource.microsoft.com/#mscorlib/system/globalization/numberformatinfo.cs,9c4284b5db21c23a