what's the bug here ?

J

Jeff Gaines

J

Jeff Gaines

[...]
NET is a wrapper round the underlying API so adds another layer.
C/C++ can be compiled to native code, C# is interpreted on the fly.

Not true at all. .NET is a wrapper for some things, but certainly not for
loops and basic arithmetic (as in the given example). C# is also not an
interpreted language. It is compiled at run-time to the native machine
code, and executed natively. There is a tiny delay during the
JIT-compilation process, but once the code is executing, it's native just
like C/C++ and other compiled languages.

Pete

So the principle is correct even if the terminology isn't.

I'm not sure about a 'tiny' delay. When running any NET application on a
freshly booted machine there is a considerable, certainly noticeable,
delay. After that (presumably some NET components loading) it's not so bad
but there's nothing to beat a fully compiled app.
 
A

Arne Vajhøj

Why are you surprised?
NET is a wrapper round the underlying API so adds another layer.
C/C++ can be compiled to native code, C# is interpreted on the fly.

100% wrong.

C++ is AOT compiled.

C# is JIT compiled.

Both are compiled to native code. In theory it could be the
same native code.

It only happen at a different time. C++ is compiled during
build. C# is compiled first time the method is called.

If someone using C# has strong preference for AOT, then
MS supplies the NGEN utility to cover that.

I believe that is practically never used. Which you can
make some conclusions from.

Arne
 
A

Arne Vajhøj

[...]
NET is a wrapper round the underlying API so adds another layer.
C/C++ can be compiled to native code, C# is interpreted on the fly.

Not true at all. .NET is a wrapper for some things, but certainly not
for loops and basic arithmetic (as in the given example). C# is also
not an interpreted language. It is compiled at run-time to the native
machine code, and executed natively. There is a tiny delay during the
JIT-compilation process, but once the code is executing, it's native
just like C/C++ and other compiled languages.

So the principle is correct even if the terminology isn't.

No. The principle was 100% wrong as well.

Arne
 
P

pamela fluente

On 29-01-2011 09:28, Jeff Gaines wrote:

No. The principle was 100% wrong as well.

Arne

Good!

But, then, how we respond to that specific misleading example (the 2
loops). Can we show, doing correctly the test, that performance
are the same even in that case. Or even better ?
 
A

Arne Vajhøj

Good!

But, then, how we respond to that specific misleading example (the 2
loops). Can we show, doing correctly the test, that performance
are the same even in that case. Or even better ?

Why bother.

If you have two programming languages X and Y and
you want to prove that X is Z percent faster than
Y, then my claim is that for Z that are not too
big, then you can always come up with a benchmark
that provide the required result.

And what does that prove? Nothing - except that
this type of benchmarks is a waste of time.

Arne
 
P

pamela fluente

[...]
But, then, how we respond to that specific misleading example (the 2
loops). Can we show, doing correctly the test, that performance
are the same even in that case. Or even better ?

It's likely that the performance can be shown to be at least on par.
"Better" is much less likely.  But like Arne says, why bother?  What is
the point?

Well the point is that personally i am pretty bothered by seeing such
statements on the web
especially if backed up by "proofs", if turns out they are false and
misleading.

I'd like to be able to "prove" with similar arguments (say "code") or
a small
test that what has been shown is untrue.

How could i put up a similarly simple experiment that shows
that ? ;-)
 
J

Jeff Gaines

What principle? You wrote "interpreted on the fly", which is completely
different from what actually happens. Where in your post was the
principle that was correct?

The principle that it doesn't run natively, interpreted may have been the
incorrect terminology but is has to be JIT-compiled. A compiled C program
runs natively.
 
A

Arne Vajhøj

The principle that it doesn't run natively, interpreted may have been
the incorrect terminology but is has to be JIT-compiled. A compiled C
program runs natively.

Stuff that is JIT compiled run just as native as stuff that
is AOT compiled.

It is just compiled at a different time.

Arne
 
A

Arne Vajhøj

[...]
But, then, how we respond to that specific misleading example (the 2
loops). Can we show, doing correctly the test, that performance
are the same even in that case. Or even better ?

It's likely that the performance can be shown to be at least on par.
"Better" is much less likely. But like Arne says, why bother? What is
the point?

Well the point is that personally i am pretty bothered by seeing such
statements on the web
especially if backed up by "proofs", if turns out they are false and
misleading.

I'd like to be able to "prove" with similar arguments (say "code") or
a small
test that what has been shown is untrue.

How could i put up a similarly simple experiment that shows
that ? ;-)

You could create another benchmark that shows a completely
different result.

And what so?

Neither the original benchmark or your benchmark will have
much similarities with a real program.

Arne
 
A

Arne Vajhøj

On this page:

http://www.elitetrader.com/vb/showthread.php?s=&threadid=213861&perpage=6&pagenumber=10

there are 2 simple test (source code), just a couple of loops

the test seems to say that c++ is much faster than c#. Is this code
flawed or what ? I don't believe that is true ... what's the problem ?

I think the bug is with the guy that did the test.

while(true);

at the bottom of both programs. WTF?

Of all possible ways of preventing the console from closing when
running from GUI that must be the clumsiest.

I tried copying the code and running it here.

C:\>csc /o+ Z.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

Z.cs(38,13): warning CS0162: Unreachable code detected

C:\>Z
Milliseconds: 47
Milliseconds: 31
Milliseconds: 47
Milliseconds: 31
Milliseconds: 47
Milliseconds: 47
Milliseconds: 62
Milliseconds: 63
Milliseconds: 31
^C

C:\>cl /Ox /EHsc Z.cpp WinMM.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

Z.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.

/out:Z.exe
Z.obj
WinMM.lib

C:\>Z
Milliseconds: 20
Milliseconds: 19
Milliseconds: 19
Milliseconds: 19
Milliseconds: 19
Milliseconds: 20
Milliseconds: 18
Milliseconds: 19
Milliseconds: 18
^C

Not nearly the same difference as shown in the link, so
something must have been done that skewed the results
there.

But still a significant difference, but the C# numbers
does not seem stable - and it is not expected
to be either with so short intervals.

Let us change to have an outer loop that iterates 100 times.

C:\>csc /o+ Z.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

Z.cs(38,13): warning CS0162: Unreachable code detected

C:\>Z
Milliseconds: 3828
Milliseconds: 3813
Milliseconds: 3828
Milliseconds: 3812
Milliseconds: 3860
Milliseconds: 3812
Milliseconds: 3828
Milliseconds: 3813
Milliseconds: 3812
^C

C:\>cl /Ox /EHsc Z.cpp WinMM.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

Z.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.

/out:Z.exe
Z.obj
WinMM.lib

C:\>Z
Milliseconds: 1942
Milliseconds: 1945
Milliseconds: 1947
Milliseconds: 1947
Milliseconds: 1936
Milliseconds: 1964
Milliseconds: 1954
Milliseconds: 2105
Milliseconds: 1942
^C

Now they are both stable.

The difference is still higher than what would be expected.

But the operation inside the loops are very simple
meaning that the performance is very dependent on
how the optimizer handles a very specific case.

Let us add some more stuff.

for( int i=0;i< 30000000; i++)
{
x = x + param1;
x = x * 2;
x = x + 1;
}

for( int i=0;i< 30000000; i++)
{
x = x - 1;
x = x / 2;
x = x - param1;
}

and only doing 10 iterations over this.

C:\>csc /o+ Z.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

Z.cs(42,13): warning CS0162: Unreachable code detected

C:\>Z
Milliseconds: 1562
Milliseconds: 1547
Milliseconds: 1578
Milliseconds: 1563
Milliseconds: 1562
Milliseconds: 1579
Milliseconds: 1546
Milliseconds: 1563
Milliseconds: 1562
^C

C:\>cl /Ox /EHsc Z.cpp WinMM.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

Z.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.

/out:Z.exe
Z.obj
WinMM.lib

C:\>Z
Milliseconds: 959
Milliseconds: 969
Milliseconds: 970
Milliseconds: 962
Milliseconds: 952
Milliseconds: 953
Milliseconds: 954
Milliseconds: 949
Milliseconds: 957
^C

The difference became smaller, but is still significant.

If you add more different stuff then I would expect the
difference to become even smaller.

What can we conclude from that?

C++ is a lot faster than C# to execute the specific
code:

for( int i=0;i< 30000000; i++)
{
x = x + param1;
}

for( int i=0;i< 30000000; i++)
{
x = x - param1;
}

so if you ever want to code that code, then you should
use C++.

But maybe better hire a programmer that has spend
time learning to program and not spend time on
language wars. In which case the code would
look like:

x += 30000000*param1;
x -= 30000000*param1;

and that would be about a million times faster.

Also note that all results apply to specific software
versions on a specific CPU. Different software and
different CPU can create different results.

Arne
 
P

pamela fluente

.....

Very interesting analysis. Does it change anything using a stopwatch
(elapsed property), instead of the environment variable ?

I think Peter was doubting that part.

running from GUI that must be the clumsiest.


LOL! that is funny. Frankly, I never used the console and i was just
wondering what was that for !!

You made me curious though. What is the canonical way to achieve
that ? ;-)
 
A

Arne Vajhøj

Very interesting analysis. Does it change anything using a stopwatch
(elapsed property), instead of the environment variable ?

When the program is modified to run a long time (and a second is
a long time), then exactly how it is measured should not
matter much,
LOL! that is funny. Frankly, I never used the console and i was just
wondering what was that for !!

You made me curious though. What is the canonical way to achieve
that ? ;-)

C#:

Console.ReadKey();

C++:

getch();

is a couple of possibilities.

Arne
 
P

pamela fluente

C#:

Console.ReadKey();

C++:

getch();

is a couple of possibilities.

Arne

Thanks ! good to know :)

I am trying with the stopwatch (stopWatch.Elapsed.Milliseconds) on a
winform and i am getting smaller elapsed values. Not much smaller but
smaller.

Pam
 
A

Arne Vajhøj

I am trying with the stopwatch (stopWatch.Elapsed.Milliseconds) on a
winform and i am getting smaller elapsed values. Not much smaller but
smaller.

If you are measuring times 20-50 ms then there are huge
deviations due to what else is going on. If you put an
outer loop around so that it runs for 1 s or more, then
it is much more stable.

Arne
 
P

pamela fluente

Hmm he has published the code generated


00B01003 83 EC 08 sub esp,8
00B01006 53 push ebx
int x = 0;

unsigned int uTicks = timeGetTime();
00B01007 8B 1D E8 20 B0 00 mov ebx,dword ptr ds:
[00B020E8h]
00B0100D 56 push esi
00B0100E FF D3 call ebx

for( int i=0;i< 30000000; i++)
00B01010 8B F7 mov esi,edi
00B01012 89 45 FC mov dword ptr [ebp-4],eax
00B01015 69 F6 80 C3 C9 01 imul esi,esi,1C9C380h
{
x = x + param1;
}

for( int i=0;i< 30000000; i++)
00B0101B B8 80 C3 C9 01 mov eax,1C9C380h
{
x = x - param1;
00B01020 2B F7 sub esi,edi
00B01022 48 dec eax
00B01023 75 FB jne 00B01020
}


Is the first loop optimized by the compiler with a single
multiplication. Or i am getting it wrong ????



Pam
 
P

pamela fluente

isn't

imul esi,esi,1C9C380h

like:

x += 30000000*param1;

just as Arne said ? ahahah compiler is smarter than
programmer !?!?

or i am misunderstanding here ?


Pam
 
A

Arne Vajhøj

Hmm he has published the code generated


00B01003 83 EC 08 sub esp,8
00B01006 53 push ebx
int x = 0;

unsigned int uTicks = timeGetTime();
00B01007 8B 1D E8 20 B0 00 mov ebx,dword ptr ds:
[00B020E8h]
00B0100D 56 push esi
00B0100E FF D3 call ebx

for( int i=0;i< 30000000; i++)
00B01010 8B F7 mov esi,edi
00B01012 89 45 FC mov dword ptr [ebp-4],eax
00B01015 69 F6 80 C3 C9 01 imul esi,esi,1C9C380h
{
x = x + param1;
}

for( int i=0;i< 30000000; i++)
00B0101B B8 80 C3 C9 01 mov eax,1C9C380h
{
x = x - param1;
00B01020 2B F7 sub esi,edi
00B01022 48 dec eax
00B01023 75 FB jne 00B01020
}


Is the first loop optimized by the compiler with a single
multiplication. Or i am getting it wrong ????

It could look like it.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top