2

I am not joking. I have a C# application, and a C++ application. They do they exact same thing, in the exact same amount of code...

...And the C# one is running faster, not just faster, but like 10 times faster.

This struck me as weird, because for one, I was running the C# app in the debugger, which should slow C# down to begin with. Then, for the reason of that C# is bytecode with huge overhead using .NET compiled into MSIL with a bunch of extra features, that should slow it down. While C++ is just pure machine code.

Here is the C# code:

static void main()
{
    ulong i = 0;
    while (i < 100000000000)
    {
        Console.WriteLine(i);
        i++;
    }
}

While this was the C++ code

int main()
{
    usigned long i = 0;
    while (i < 100000000000)
    {
        cout << i << endl;
        i++;
    }
    return 0;
}

They are just counting and displaying a number. The C++ one would be at 1000, while the C# one would be at 7000. ( 7x faster)

I even tried compiling both of them, and running them without the debugger using command prompt with the command: cplusplus.exe && csharp.exe

Yeah, I know maybe this question is "offtopic" :P or maybe it is "not clear what's being asked for". :/ But please, someone explain this to me.

If this matters, I am using this CPU: Intel i7 2.5 Ghz.

EDIT: I did the cout << i << "\n"; idea, plus the std::ios_base::sync_with_stdio(false); idea, without any luck or change in results.

EDIT 2: I tried C's printf() and it was much, much faster. 3x faster than C#.

People told me that IO stream was very slow, so I then tried them both without writing to the console, and C++ was still significantly faster than C#.

In conclusion, Writeline() is much faster than cout, and printf() is much faster than both. So writing to the console is the only thing that slows it down.

TLDR: printf() wins, and console writing slows stuff down.

plkana
  • 61
  • 1
  • 4
  • 5
    Your program is I/O bound, so you are really comparing the I/O stacks of the two runtimes, not the languages. – Raymond Chen Aug 05 '15 at 02:56
  • Also, did you compile your C++ in release mode? iostreams have an awful lot of indirection that boils away significantly with optimizations turned on. – Cameron Aug 05 '15 at 02:57
  • 3
    How are you benchmarking them? I believe that C#'s `WriteLine` doesn't flush after each line *if redirected from the console*, while in C++ `endl` explicitly requests a flush regardless.... – Tony Delroy Aug 05 '15 at 03:05
  • Lol, this is not "an application", it is just a small client over some API that looks like it does the same thing, but depends a lot on internal config flags. The exact same question got posted here already. – v.oddou Aug 05 '15 at 03:23
  • Sorry I confused a Python related question. But honestly similar enough to make the brain connection. http://stackoverflow.com/questions/9371238/why-is-reading-lines-from-stdin-much-slower-in-c-than-python?rq=1 – v.oddou Aug 05 '15 at 03:24
  • Do something else useful. I/O itself is already far slower than the capability of the CPUs – phuclv Aug 05 '15 at 03:40
  • Use `cout << i << '\n'`, not `cout << i << "\n";`. `printf` should be slower, as it needs to parse the format string during runtime, and `cout` will be optimized at the compile time. If `printf` is wrong, there's probably some problem with your benchmark. – phuclv Aug 05 '15 at 17:25

4 Answers4

10

Your code is inefficient because:

  • The C++ stream object is in sync with C's stdio by default which makes it slow.
  • You're using endl which is further making it slow.

Fixing both these issues, you've this code:

int main()
{
    std::ios_base::sync_with_stdio(false);

    usigned long i = 0;
    while (i < 100000000000)
    {
        cout << i << '\n'; //use \n, not endl
        i++;
    }
    return 0;
}

Compile this as (must use optimization flag whatever compiler you're using):

$ g++ main.cpp -O3 -o run.test
$ time ./run.test

For explanation of both sync_with_stdio(false) and endl, read my answer here:

Hope that helps.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 2
    In my experience `sync_with_stdio` is a red herring. I/O stream performance inherently sucks no matter what flags you use it with. – user541686 Aug 05 '15 at 03:07
  • 2
    @t.c. It is like 11 on an amp. – Yakk - Adam Nevraumont Aug 05 '15 at 03:25
  • When you take a step back, it now appears to me that probably the OP was actually trying to measure the `i++` part of the program, but didn't realize the overhead incurred by outputing was the bottleneck ? This brings me to the next issue, removing the output will allow the optimizer to get rid of the loop entirely. Even printing it at the end, the compiler could prepare the result directly. And this is why I said above "this is not an application". – v.oddou Aug 05 '15 at 03:29
  • I/O streams are inherently slow, no doubt, but `sync_with_stdio` further makes it slow. Please do experiment with it. – Nawaz Aug 05 '15 at 04:08
3

I think you've not been careful enough in your evaluation. I recreated your test with C++ proving massively faster as detailed below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSScratch
{
    class Program
    {
        static void Main(string[] args)
        {
            ulong i = 0;
            while (i < 1000000)
            {
                Console.WriteLine(i);
                i++;
            }
        }
    }
}

I built the above in VS2013 Release mode to CSScratch.exe, which I then timed (under cygwin bash) with output redirected so file-system writing time wasn't counted. Results were fairly consistent, the fastest of five runs being:

time ./CSScratch.exe > NUL

real    0m17.175s
user    0m0.031s
sys     0m0.124s

The C++ equivalent:

#include <iostream>

int main()
{
    std::ios_base::sync_with_stdio(false);


    unsigned long i = 0;
    while (i < 1000000)
    {
        std::cout << i << '\n';
        i++;
    }
}

Also compiled with VS2013:

cl /EHsc /O2 output.cc
time ./output > NUL

The slowest of five runs:

real    0m1.116s
user    0m0.000s
sys     0m0.109s

which is still faster (1.116 seconds) than the fastest of C# runs (17.175 seconds).

Some of the time for both versions is taken by loading / dynamic linking, initialisation etc.. I modified the C++ version to loop 10x more, and it still only took 9.327 seconds - about half the time C# needed for a tenth of the workload.

(You could further tune the C++ version by setting a larger output buffer, but that's not normally needed).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
1

Tony D makes an excellent point about buffering in the comments.
Add this to your C# code and time it again:

static void main()
{
    ulong i = 0;
    while (i < 100000000000)
    {
        Console.WriteLine(i);
        Console.Out.Flush();
        i++;
    }
}
1

If you replace

cout << i << endl;

with

printf("%d\n", i);

the result will be close to .net WriteLine.

In general, just a fact you are writing on C++ or C does not automatically mean that your code will be faster. Fast code is not only the language syntax. It also requires some of knowledge of underlying things like hardware and OS internals.

I mean properly used C++ gives much better results, at least on not trivial tasks.

Eugene
  • 3,335
  • 3
  • 36
  • 44