30% difference in speedof C# vs C++ for math?

R

Rich

I was considering C# for developing a scientific application, but I have
noticed a ~30% difference between VC++ .NET and C# on the same machine,
under identical conditions:

double a = 0,b = 0, c = 0, d = 0, e = 0;
for(int n = 0; n != 6000000; n++)
{
a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
}

It takes 2300ms in VB.NET, 1000ms in C# but only 700ms in VC++

Does this sound right?

Thanks.
Richard
 
R

realfun

did you build in release version?
did you open the optimizing parameter in the building process?
is the VC++ code native or managed?

all of these will affect the performance.
 
R

Rich

did you build in release version?
did you open the optimizing parameter in the building process?
is the VC++ code native or managed?

all of these will affect the performance.

1. Both were run in Release mode (C# and VC++).
2. The VC++ program was optimized for speed. I could not find a similar
option for C#
3. The VC++ code is native.

Is there an option to maximize speed in a compiled C# application?

Richard
 
J

Johann Blake

Richard,

If you need that kind of speed, buy a math component (and one
particular to your type of application) and use C# to develop the GUI
and business logic. That makes far more sense than writing everything
in C++.

Best Regards
Johann Blake
 
R

Rich

Johann Blake said:
Richard,

If you need that kind of speed, buy a math component (and one
particular to your type of application) and use C# to develop the GUI
and business logic. That makes far more sense than writing everything
in C++.

Best Regards
Johann Blake

C++ is OK for me, I have been using it for 15 years. But I thought I would
gain some type of advantage by switching to C#

Well apparently not, because I'm not sure if I would want to do something
crazy like:

ClumsyThirdPartyMathLibrary clumsy = new ClumsyThirdPartyMathLibrary();
double a = 0,b = 0, c = 0, d = 0, e = 0;
for(int n = 0; n != 6000000; n++)
{
a =
clumsy.Multply(clumsy.Add(clumsy.Subtract(clumsy.Divide(clumsy.Add(clumsy.Su
btract(clumsy.Divide(clumsy.Multiply(clumsy.Mod(n, 5) * 2), 3) 4), 6), 3),
n), n), 2);
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
}

I couldn't even finish the first line. I've got just 11,000 more to go.
C# should be faster. One shouldn't have to resort to clumsy stuff like that.

Richard
 
J

Johann Blake

Richard,

I should have made my point much clearer. You don't use a third party
math library to do basic math. The library should contain the math
functions pertinent to what you want to accomplish. For example, if you
need to run a DSP FFT algorithm on an analog signal, you use a DSP
library with a FFT function.

Since you already know C++, write these functions yourself in C++ and
call them from C#. That is what I am doing at the moment. All my "math"
stuff is in C++ but the actual GUI and business logic is C#.

Developing GUI and business logic in C# makes far more sense and has
far more advantageous than doing it in C++.

Johann
 
C

Christoph Nahr

I couldn't even finish the first line. I've got just 11,000 more to go.
C# should be faster. One shouldn't have to resort to clumsy stuff like that.

Who said it "should" be faster? Santa Claus?

Different languages are better at different things. C# is great at
things like speed of development, clarity of code, runtime linking,
memory management. C++ is great at things like hardware access,
porting to many different systems, and raw speed.

Your experience is the same as mine, by the way. In numerical code,
C# is only 50-80% the speed of C++. That's how it is, for now. But
(Visual) C++ is a fairly stable language that has had many years of
gradual optimizer improvements while C# and .NET are still getting a
ton of new features with each release (example: generics in 2.0,
embedded database queries planned for 3.0). Once the Microsoft teams
start focusing on the optimizer numerical code might improve, too.
 
O

Octavio Hernandez

Rich,

a) Your code does not really test floating point arithmetic. Since variable
n and all the constants used are integers, you're only doing integer
arithmetic there...

b) If you're comfortable with C++, maybe you should consider using Visual
C++ 2005. It offers most of the productivity-enhancement tools that there
are in VS 2005 for C#, and it's the only language that allows you to mix
native and managed code. This will allow you to recompile your
math-intensive code as native, if the tests show that managed code is
significantly slower than native, with minimum effort.

Regards - Octavio
 
W

Willy Denoyette [MVP]

I can't believe there is such a huge difference between VB and C#, there
must be something wrong here.
Mind to post the whole code?

Willy.
 
M

Mattias Sjögren

I can't believe there is such a huge difference between VB and C#, there
must be something wrong here.
Mind to post the whole code?

I'm guessing that the VB code uses the / operator which performs
implicit floating point division (as opposed to \), whereas the C#
code just does integer math like Octavio said. That would account for
at least some of the difference.



Mattias
 
W

Willy Denoyette [MVP]

Mattias Sjögren said:
I'm guessing that the VB code uses the / operator which performs
implicit floating point division (as opposed to \), whereas the C#
code just does integer math like Octavio said. That would account for
at least some of the difference.

No, this is not what I'm seeing when looking at the IL code (both VB and
C#), all oprations are performed on floats. The only difference is that the
VB compiler optimizes some constant expressions like n Mod 5 *2 / 3 where
the 5 *2 / 3 part is pre-calculated as 3.3333333333333335.
I changed the code a bit such that I'm using the results of the calcs.
outside the loop, and the results I'm getting show no real (<20%)
difference between VB.NET and C#, but a huge difference between VB/C# and C
, more precisely a the C version is almost 3 times faster, just like the OP
noticed:
<It takes 2300ms in VB.NET, 1000ms in C# but only 700ms in VC++.>, but again
the C# result seems wrong, but it's hard to tell without seeing the complete
code.

Now I'm gonna take a look at the assembly code generated from the C code and
compare it with the JIT'd code.

Willy.
 
R

Rich

a) A similar floating point test created a wider gap in performance, where
VC++ came in at 1100ms and C# came in at 1980ms.

b) Good point, that is what I've been considering.

Richard
 
W

Willy Denoyette [MVP]

Willy Denoyette said:
No, this is not what I'm seeing when looking at the IL code (both VB and
C#), all oprations are performed on floats. The only difference is that
the VB compiler optimizes some constant expressions like n Mod 5 *2 / 3
where the 5 *2 / 3 part is pre-calculated as 3.3333333333333335.
I changed the code a bit such that I'm using the results of the calcs.
outside the loop, and the results I'm getting show no real (<20%)
difference between VB.NET and C#, but a huge difference between VB/C# and
C , more precisely a the C version is almost 3 times faster, just like the
OP noticed:
<It takes 2300ms in VB.NET, 1000ms in C# but only 700ms in VC++.>, but
again the C# result seems wrong, but it's hard to tell without seeing the
complete code.

Now I'm gonna take a look at the assembly code generated from the C code
and compare it with the JIT'd code.

Willy.

Ok, as expected the C++ compiler backend does a better job for floating
point operations. He makes optimal use of the FPU registerstack and FPU
register based float ops. The JIT'er is not quite optimized and moves FPU
registers back and forth to the CPU stack instead of using FPU register ops.
Seems like floating point operations is not very high on the priority list
of the CLR performance team.

Willy.
 
J

James Curran

You are seeing the effect of the C# compilers less-aggressive
optimisizer (compared to the C++'s compiler) --- when given REALLY DUMB CODE
to work on.

To demostrate, VC# 2003, release build, reduces that code to

for (int n= 0; n!= 6000000; n++)
{
int num2 = ((n% 5) * 2) / 3;
double num3 = ((((double) (n* 3)) / 3.5) * 2) / 3;
int num4 = ((n/ 2) * 2) / 3;
}

On the other hand : VC++ 2003, release build, reduces that code to:




That's right. C++ completely eliminates the limit, as nothing that happens
inside the loop, has any effect on anything outside the loop. The 700ms
you see is probably just the startup code.

Change your test to:

double a = 0,b = 0, c = 0, d = 0, e = 0;
double total = 0;
for(int n = 0; n != 6000000; n++)
{
a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
total += a + b + c + d + e;
}
Console.WriteLine("total = {0}", total);

And you'll probably get very different (from your eariler results) and very
similar (among the different languages) results.

Well, actually, The C++ will still win by a lot, because the optimizer is
still able to reduce the code to:
public static int modopt(CallConvCdecl) main()
{
double num5 = 0;
int num1 = 0;
int num3 = 0;
int num2 = 0;
do
{
double num4 = num1;
double num6 = num3;
num5 = (((((((((num2 * 0.19047619047619047) - 4) + 2) - num4) +
num6) + (((((num4 * 2.3) - 4) + 2) - num4) + num6)) + ((num1 + (((num1 % 5)
<< 1) / 3)) - 2)) + ((num1 + (((num1 / 2) << 1) / 3)) - 2)) + (num3 - 1)) +
num5;
num1++;
num2 += 3;
num3 += 2;
}
while (num2 != 18000000);
Console.WriteLine(num5);
return 0;

Pretty cool huh?

But still, we aren't test either compilers abilty to perform math
operations, as mush as we're testing their abilities to optimize REALLY DUMB
CODE. Stick a real world example into your test harness and see what
results you get.


--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
W

Willy Denoyette [MVP]

James,
public static int modopt(CallConvCdecl) main()
This is ME C++ code right? I had the (wrong?) impression that the OP was
talking about native C++ and not about managed C++. I wish posters could be
more explicit when asking questions and use C++, Managed C++ and C++/CLI
instead of VC.NET, this would be less confusing.
In my replies I was only talking about native C++.

Well back to this:
Well, actually, The C++ will still win by a lot, because the optimizer is
still able to reduce the code to:

You are right the (front-end) optimizer does a better job in generating the
IL than the others (C#, VB.NET) the final result being Managed C++ ~20%
faster than C# and VB.NET. However, the difference between unmanaged and
managed code for this sample (yes, I make sure the loop executes), is ~300%,
which illustrates that the JIT compiler could do a much better job when
dealing with floats.

Willy.



James Curran said:
You are seeing the effect of the C# compilers less-aggressive
optimisizer (compared to the C++'s compiler) --- when given REALLY DUMB
CODE
to work on.

To demostrate, VC# 2003, release build, reduces that code to

for (int n= 0; n!= 6000000; n++)
{
int num2 = ((n% 5) * 2) / 3;
double num3 = ((((double) (n* 3)) / 3.5) * 2) / 3;
int num4 = ((n/ 2) * 2) / 3;
}

On the other hand : VC++ 2003, release build, reduces that code to:




That's right. C++ completely eliminates the limit, as nothing that
happens
inside the loop, has any effect on anything outside the loop. The 700ms
you see is probably just the startup code.

Change your test to:

double a = 0,b = 0, c = 0, d = 0, e = 0;
double total = 0;
for(int n = 0; n != 6000000; n++)
{
a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
total += a + b + c + d + e;
}
Console.WriteLine("total = {0}", total);

And you'll probably get very different (from your eariler results) and
very
similar (among the different languages) results.

Well, actually, The C++ will still win by a lot, because the optimizer is
still able to reduce the code to:
public static int modopt(CallConvCdecl) main()
{
double num5 = 0;
int num1 = 0;
int num3 = 0;
int num2 = 0;
do
{
double num4 = num1;
double num6 = num3;
num5 = (((((((((num2 * 0.19047619047619047) - 4) + 2) - num4) +
num6) + (((((num4 * 2.3) - 4) + 2) - num4) + num6)) + ((num1 + (((num1 %
5)
<< 1) / 3)) - 2)) + ((num1 + (((num1 / 2) << 1) / 3)) - 2)) + (num3 - 1))
+
num5;
num1++;
num2 += 3;
num3 += 2;
}
while (num2 != 18000000);
Console.WriteLine(num5);
return 0;

Pretty cool huh?

But still, we aren't test either compilers abilty to perform math
operations, as mush as we're testing their abilities to optimize REALLY
DUMB
CODE. Stick a real world example into your test harness and see what
results you get.


--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com

Rich said:
I was considering C# for developing a scientific application, but I have
noticed a ~30% difference between VC++ .NET and C# on the same machine,
under identical conditions:

double a = 0,b = 0, c = 0, d = 0, e = 0;
for(int n = 0; n != 6000000; n++)
{
a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
}

It takes 2300ms in VB.NET, 1000ms in C# but only 700ms in VC++

Does this sound right?

Thanks.
Richard
 
J

James Curran

Willy Denoyette said:
This is ME C++ code right? I had the (wrong?) impression that the OP was
talking about native C++ and not about managed C++.

True enough. I had intended to create a Native C++ app, but the default
in VS.net is Management C++, and by the time I noticed, I figured it would
make much difference to my point.

However, using Lutz Roeder's Reflector on the managed C++ Assembly was
the only way I know of to get the effective C++ code (actually, it was C# --
did anyone notice?) of the optimizer output.

--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
R

Rich

I am the original poster, and I was talking about Native, UNmanaged C++
code. My apologies to both James and Willy for not making that clear, but at
least Willy's assumption was correct.

James, the code is not "really dumb code", if you pay attention to the "n"
in the equations and in my test, the code had scope outside the loop. It was
not reduced to nothingness. Each line was evaluated several million times. I
tried inserting all values into an array which had scope outside the loop.
Each line was evaluated. The results were the same.

The point is of course that the JIT compiler is not as efficient when
dealing with floating point operations. VC++ 6 and VC++ .NET (native) are at
least 30% and up to 100% faster than C# when dealing with floating point
calculations. That's the bottom line.

Richard



Willy Denoyette said:
James,
public static int modopt(CallConvCdecl) main()
This is ME C++ code right? I had the (wrong?) impression that the OP was
talking about native C++ and not about managed C++. I wish posters could be
more explicit when asking questions and use C++, Managed C++ and C++/CLI
instead of VC.NET, this would be less confusing.
In my replies I was only talking about native C++.

Well back to this:
Well, actually, The C++ will still win by a lot, because the optimizer is
still able to reduce the code to:

You are right the (front-end) optimizer does a better job in generating the
IL than the others (C#, VB.NET) the final result being Managed C++ ~20%
faster than C# and VB.NET. However, the difference between unmanaged and
managed code for this sample (yes, I make sure the loop executes), is ~300%,
which illustrates that the JIT compiler could do a much better job when
dealing with floats.

Willy.



James Curran said:
You are seeing the effect of the C# compilers less-aggressive
optimisizer (compared to the C++'s compiler) --- when given REALLY DUMB
CODE
to work on.

To demostrate, VC# 2003, release build, reduces that code to

for (int n= 0; n!= 6000000; n++)
{
int num2 = ((n% 5) * 2) / 3;
double num3 = ((((double) (n* 3)) / 3.5) * 2) / 3;
int num4 = ((n/ 2) * 2) / 3;
}

On the other hand : VC++ 2003, release build, reduces that code to:




That's right. C++ completely eliminates the limit, as nothing that
happens
inside the loop, has any effect on anything outside the loop. The 700ms
you see is probably just the startup code.

Change your test to:

double a = 0,b = 0, c = 0, d = 0, e = 0;
double total = 0;
for(int n = 0; n != 6000000; n++)
{
a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
total += a + b + c + d + e;
}
Console.WriteLine("total = {0}", total);

And you'll probably get very different (from your eariler results) and
very
similar (among the different languages) results.

Well, actually, The C++ will still win by a lot, because the optimizer is
still able to reduce the code to:
public static int modopt(CallConvCdecl) main()
{
double num5 = 0;
int num1 = 0;
int num3 = 0;
int num2 = 0;
do
{
double num4 = num1;
double num6 = num3;
num5 = (((((((((num2 * 0.19047619047619047) - 4) + 2) - num4) +
num6) + (((((num4 * 2.3) - 4) + 2) - num4) + num6)) + ((num1 + (((num1 %
5)
<< 1) / 3)) - 2)) + ((num1 + (((num1 / 2) << 1) / 3)) - 2)) + (num3 - 1))
+
num5;
num1++;
num2 += 3;
num3 += 2;
}
while (num2 != 18000000);
Console.WriteLine(num5);
return 0;

Pretty cool huh?

But still, we aren't test either compilers abilty to perform math
operations, as mush as we're testing their abilities to optimize REALLY
DUMB
CODE. Stick a real world example into your test harness and see what
results you get.


--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com

Rich said:
I was considering C# for developing a scientific application, but I have
noticed a ~30% difference between VC++ .NET and C# on the same machine,
under identical conditions:

double a = 0,b = 0, c = 0, d = 0, e = 0;
for(int n = 0; n != 6000000; n++)
{
a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
}

It takes 2300ms in VB.NET, 1000ms in C# but only 700ms in VC++

Does this sound right?

Thanks.
Richard
 
J

James Curran

James, the code is not "really dumb code", if you pay attention to the "n"
in the equations and in my test, the code had scope outside the loop. It was
not reduced to nothingness. Each line was evaluated several million times. I
tried inserting all values into an array which had scope outside the loop.
Each line was evaluated. The results were the same.

Hey, I looked at the C++ compiler output. You want to see it? Here it
is:


..global ?main@@$$HYAHXZ ; main
?main@@$$HYAHXZ: ; main
; .proc.def D:I()
; Function Header:
; max stack depth = 1
; function size = 2 bytes
; local varsig tk = 0x0
; Exception Information:
; 0 handlers, each consisting of filtered handlers
; .proc.beg
; 12 : double a = 0,b = 0, c = 0, d = 0, e = 0;
; 13 : double total = 0;
; 14 : for(int n = 0; n != 6000000; n++)
; 15 : {
; 16 : a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 17 : b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 18 : c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 19 : d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 20 : e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 21 : total += a + b + c + d + e;
; 22 : }
; 23 : // Console::WriteLine(total);
; 24 : return 0;
0000c 16 ldc.i.0 0 ; i32 0x0
0000d 2a ret
..end ?main@@$$HYAHXZ ; main
; .proc.end.i4
text ENDS
END

Look carefully: the only code between the start of main and .end?main loads
the exit value with zero & returns. It's all of two bytes long: 16 2A. It
doesn't matter that n exists outside the loop --- you only use it to create
a - e, and you don't use them for anything, so they are unnecessary, and are
removed. In fact, in the code I compiled there, I even left in the counter
"total", which is defined outside the loop. BUT, since I commented out
where I print it out, it became unecessary and was removed. Unless you read
some value from that array that you put the values into, it would be
unnecessary and be removed.

--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
W

Willy Denoyette [MVP]

James,

Again, the OP is talking about "unmanaged" C++, the output you show is
managed C++ generated IL....

Willy.

James Curran said:
James, the code is not "really dumb code", if you pay attention to the
"n"
in the equations and in my test, the code had scope outside the loop. It was
not reduced to nothingness. Each line was evaluated several million
times. I
tried inserting all values into an array which had scope outside the
loop.
Each line was evaluated. The results were the same.

Hey, I looked at the C++ compiler output. You want to see it? Here it
is:


.global ?main@@$$HYAHXZ ; main
?main@@$$HYAHXZ: ; main
; .proc.def D:I()
; Function Header:
; max stack depth = 1
; function size = 2 bytes
; local varsig tk = 0x0
; Exception Information:
; 0 handlers, each consisting of filtered handlers
; .proc.beg
; 12 : double a = 0,b = 0, c = 0, d = 0, e = 0;
; 13 : double total = 0;
; 14 : for(int n = 0; n != 6000000; n++)
; 15 : {
; 16 : a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 17 : b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 18 : c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 19 : d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 20 : e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 21 : total += a + b + c + d + e;
; 22 : }
; 23 : // Console::WriteLine(total);
; 24 : return 0;
0000c 16 ldc.i.0 0 ; i32 0x0
0000d 2a ret
.end ?main@@$$HYAHXZ ; main
; .proc.end.i4
text ENDS
END

Look carefully: the only code between the start of main and .end?main
loads
the exit value with zero & returns. It's all of two bytes long: 16 2A. It
doesn't matter that n exists outside the loop --- you only use it to
create
a - e, and you don't use them for anything, so they are unnecessary, and
are
removed. In fact, in the code I compiled there, I even left in the
counter
"total", which is defined outside the loop. BUT, since I commented out
where I print it out, it became unecessary and was removed. Unless you
read
some value from that array that you put the values into, it would be
unnecessary and be removed.

--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
R

Rich

Also that is not the complete code that I tested with. The data was inserted
into an array and used outside the loop.

Richard

Willy Denoyette said:
James,

Again, the OP is talking about "unmanaged" C++, the output you show is
managed C++ generated IL....

Willy.

James Curran said:
James, the code is not "really dumb code", if you pay attention to the
"n"
in the equations and in my test, the code had scope outside the loop.
It
was
not reduced to nothingness. Each line was evaluated several million
times. I
tried inserting all values into an array which had scope outside the
loop.
Each line was evaluated. The results were the same.

Hey, I looked at the C++ compiler output. You want to see it? Here it
is:


.global ?main@@$$HYAHXZ ; main
?main@@$$HYAHXZ: ; main
; .proc.def D:I()
; Function Header:
; max stack depth = 1
; function size = 2 bytes
; local varsig tk = 0x0
; Exception Information:
; 0 handlers, each consisting of filtered handlers
; .proc.beg
; 12 : double a = 0,b = 0, c = 0, d = 0, e = 0;
; 13 : double total = 0;
; 14 : for(int n = 0; n != 6000000; n++)
; 15 : {
; 16 : a = n % 5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 17 : b = n * 2.3 - 1 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 18 : c = n * 3 / 3.5 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 19 : d = n + 1 * 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 20 : e = n / 2 *2 / 3 - 4 + 6 / 3 - n + n * 2;
; 21 : total += a + b + c + d + e;
; 22 : }
; 23 : // Console::WriteLine(total);
; 24 : return 0;
0000c 16 ldc.i.0 0 ; i32 0x0
0000d 2a ret
.end ?main@@$$HYAHXZ ; main
; .proc.end.i4
text ENDS
END

Look carefully: the only code between the start of main and .end?main
loads
the exit value with zero & returns. It's all of two bytes long: 16 2A. It
doesn't matter that n exists outside the loop --- you only use it to
create
a - e, and you don't use them for anything, so they are unnecessary, and
are
removed. In fact, in the code I compiled there, I even left in the
counter
"total", which is defined outside the loop. BUT, since I commented out
where I print it out, it became unecessary and was removed. Unless you
read
some value from that array that you put the values into, it would be
unnecessary and be removed.

--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 

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