Shpaget
Posts: 17
Joined: Wed Mar 14, 2012 8:41 am

Re: Large numbers in C#

Wed Apr 18, 2012 8:31 pm

I've noticed that C# appears to interpret 1 000 000 000 and 1e9 somewhat differently.

For example:

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

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();

stopwatch.Start();

for (int i = 0; i < 1000000000; i++)
{

}

stopwatch.Stop();

Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
Console.ReadKey();
}
}
}

The code measures the time it takes for the computer to count to one billion. On my machine it takes approximately 4,08 seconds (moving the mouse increases this time, so I don't move it).

However, if I express one billion as 1e9 the time required for the computer to go through the code drops to 3,65.

That is around 10% difference. Can anybody offer an explanation?

Thanks

User avatar
nick.mccloud
Posts: 804
Joined: Sat Feb 04, 2012 4:18 pm

Re: Large numbers in C#

Wed Apr 18, 2012 8:43 pm

Please don't be surprised if you don't get too many responses - C# isn't native to Linux let alone a RPi so there will be a limited number of people that can respond.

The only thought that I had is that the compiler may be treating 1000000000 as an integer and 1e9 may be treated as a float - you could check for type and see what the storage implications are and what that may mean to the increment & comparison of i.

Shpaget
Posts: 17
Joined: Wed Mar 14, 2012 8:41 am

Re: Large numbers in C#

Wed Apr 18, 2012 8:56 pm

Well, these forums seem to be full of smart people, so I guess somebody will come along who has experience. I understand C# is not native to RPi, but after all nobody here is native to RPi

Compiler does appear to treat 1e9 as float.

Trying

int a = 1e9;

results in an Error "Cannot implicitly convert 'double' to 'int'..."

But that further complicates the question. If I remember my classes correctly, doubles need more memory than integers, which should make them slower to deal with.

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Large numbers in C#

Wed Apr 18, 2012 8:59 pm

Yeah, but a double ets shoved into a floating point register (and may well stay there, meaning less ,emory bandwith usage), and fp math may well happen out of order on a separate fpu.

User avatar
johnbeetem
Posts: 945
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Mountains
Contact: Website

Re: Large numbers in C#

Wed Apr 18, 2012 9:53 pm

Given that this is Microsoft, my hypothesis is that they do all arithmetic in double so if one argument is already double it saves time.  They use double since C# uses code from the original Microsoft Basic interpreter

emg
Posts: 88
Joined: Wed Jan 11, 2012 11:01 pm

Re: Large numbers in C#

Wed Apr 18, 2012 9:53 pm

maybe forcing a ulong and/or compiler optimization?

User avatar
SN
Posts: 1014
Joined: Mon Feb 13, 2012 8:06 pm
Location: Romiley, UK
Contact: Website

Re: Large numbers in C#

Wed Apr 18, 2012 10:36 pm

John Beetem said:


Given that this is Microsoft, my hypothesis is that they do all arithmetic in double so if one argument is already double it saves time.  They use double since C# uses code from the original Microsoft Basic interpreter


Really?  I'm interested in any evidence for this.
Steve N – binatone mk4->intellivision->zx81->spectrum->cbm64->cpc6128->520stfm->pc->raspi ?

error404
Posts: 351
Joined: Wed Dec 21, 2011 11:49 pm

Re: Large numbers in C#

Thu Apr 19, 2012 12:04 am

On my (x86, mono) machine the 1e9 version of your code is much slower (0.42 vs. 1.55), as I would expect. Looking at the generated CIL there is an additional type conversion before the comparison occurs (comparison becomes double < double).

I have no idea why this would be faster on your platform than the int < int version. The rest of the generated code is functionally identical. Examine the CIL yourself and see if you can figure it out.

User avatar
johnbeetem
Posts: 945
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Mountains
Contact: Website

Re: Large numbers in C#

Thu Apr 19, 2012 12:53 am

SN said:


John Beetem said:


Given that this is Microsoft, my hypothesis is that they do all arithmetic in double so if one argument is already double it saves time.  They use double since C# uses code from the original Microsoft Basic interpreter


Really?  I'm interested in any evidence for this.


When I make something up for humorous purposes, I try to include extra detail so that it sounds more plausible   The great thing about making up silly things about Microsoft is that they almost always sound plausible, probably because they pale in comparison to the actual silly things Microsoft does, like "Bob".

User avatar
jojopi
Posts: 3233
Joined: Tue Oct 11, 2011 8:38 pm

Re: Large numbers in C#

Thu Apr 19, 2012 1:48 am

John Beetem said:

The great thing about making up silly things about Microsoft is that they almost always sound plausible, probably because they pale in comparison to the actual silly things Microsoft does, like "Bob".
Or, more relevant to this discussion, Excel 2007's "850 * 77.1 = 100000" bug.  Apparently they wrote their own floating point formatting code in x86-16 assembler (!), and then updated it incorrectly to 32bit (in 2007!).

http://lomont.org/Math/Papers/.....007Bug.pdf

Shpaget
Posts: 17
Joined: Wed Mar 14, 2012 8:41 am

Re: Large numbers in C#

Thu Apr 19, 2012 6:30 am

error404 said:


On my (x86, mono) machine the 1e9 version of your code is much slower (0.42 vs. 1.55), as I would expect. Looking at the generated CIL there is an additional type conversion before the comparison occurs (comparison becomes double < double).

I have no idea why this would be faster on your platform than the int < int version. The rest of the generated code is functionally identical. Examine the CIL yourself and see if you can figure it out.



Interesting.

In the interest of hardware details, I have Intel Core 2 4400 @2 GHz, with 2 GB of RAM

Running on 32 bit XP.

As for the CIL bit of your post, I have to admit I have no idea what you are talking about. (I've just started C#, and my other programing skills are about decade and a half out of practice.)

error404
Posts: 351
Joined: Wed Dec 21, 2011 11:49 pm

Re: Large numbers in C#

Thu Apr 19, 2012 7:40 pm

C# is a .NET language, which means it compiles to the Common Language Infrastructure (CLI) bytecode (which runs under the Common Language Runtime), which is basically an architecture on its own. It is matched to an 'assembly' language called Common Intermediate Language (CIL) that describes CLI code. So if you've got a .NET executable, it can be decompiled to CIL assembly and analyzed, just like you might analyze the assembly output of a C compiler to try and figure out issues like this. It won't give you perspective on what the runtime does with JIT and optimization, but it will show you differences between the machine code that your source produces (and that the runtime is executing); if the machine code is identical then there's no explanation for the difference.

Mono includes a disassembler 'monodis' that will do this. I'm sure Microsoft has a similar tool in their development kit, but I haven't worked with .NET in a long time.

Shpaget
Posts: 17
Joined: Wed Mar 14, 2012 8:41 am

Re: Large numbers in C#

Thu Apr 19, 2012 8:07 pm

Oh, I think I get the general idea now. Thanks for the explanation, however, reading machine code is a bit out of my league.

Do you expect it to be exactly the same?

error404
Posts: 351
Joined: Wed Dec 21, 2011 11:49 pm

Re: Large numbers in C#

Thu Apr 19, 2012 11:08 pm

If it were the same, it should run the same, and the difference you see would be rather shocking. Computers are deterministic and if the code were identical, it should be executed identically. So there must be some difference.

However as has been pointed out, the literal '1e9' is interpreted as floating point in C#, as opposed to 1000000000, which is integer. There should be some difference, though it may not tell you why the FP version is faster. That's probably a mystery that's hidden in the bowels of the runtime. Puzzling though.

I just ran the same executables I created with Mono on my x64 Win7 machine and the difference is even bigger - integer 0.075s FP 1.1s.

Are you sure?

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Large numbers in C#

Fri Apr 20, 2012 3:45 am

I can verify that on .NET 3.5 VS2008, floating point is faster, but only if you don't switch on optimisation. If you allow optimisations then the integer code is faster.

I surmise therefore that the unoptimised CL code is more sub-optimal in the integer case.

Shpaget
Posts: 17
Joined: Wed Mar 14, 2012 8:41 am

Re: Large numbers in C#

Fri Apr 20, 2012 5:55 am

rurwin said:


I can verify that on .NET 3.5 VS2008, floating point is faster, but only if you don't switch on optimisation. If you allow optimisations then the integer code is faster.

I surmise therefore that the unoptimised CL code is more sub-optimal in the integer case.



Does optimisation make integers go faster, floats slower or both go faster?

error404, Are you asking me if I was sure? About what?

So your Mono code shows opposite time difference. I guess that would come from a different compiler?

What is interesting, making numbers larger (2 billion for example) makes the bigger difference, so it appears that the numbers are converted one by one in each iteration of for loop and not once during initialisation of the program.

Chris.Rowland
Posts: 239
Joined: Thu Jan 12, 2012 5:45 pm

Re: Large numbers in C#

Fri Apr 20, 2012 8:10 am

You may find that Stack Overflow is a good place to ask this sort of question.  It's full of experts who want to answer software questions.  The signal to noise ratio is better than most places on the Internet.

http://stackoverflow.com/

Return to “Off topic discussion”