4

Possible Duplicate:
Why does C# execute Math.Sqrt() more slowly than VB.NET?

I'm running into an interesting problem, wherein I have code in VB.net and the exact same code in C++. I'd expect C++ to naturally run a tad faster than VB.net, but instead I'm getting the exact opposite: VB.net runs more than twice as fast as C++. The program iterates through all the numbers from 1 to 2,000,000, determines if they are prime or not, and adds all the primes together. Here are the following snippets:

C++

void problem10(void)
{   
   clock_t init, final;
   init=clock();

   int maxVal = 2000000;
   long long sumOfPrimes = 0;
   for (long i = 2; i < maxVal; i++)
   {
      if (isPrime(i))
      {
         sumOfPrimes+= i;
      }
   }
   final = clock() - init;
   cout << (double)final / ((double)CLOCKS_PER_SEC);
   cout << "The sum of all the prime numbers below " << maxVal << " is " << sumOfPrimes;
}

bool isPrime(int NumToCheck)
{
   for (int i = 2; i <= (sqrt((double)NumToCheck)); i++)
   {
      if (NumToCheck % i == 0)
      {
         return false;
      }
   }
   return true;
}

C++ output:

3.846The sum of all the prime numbers below 2000000 is 142913828922

And here's the exact same thing, only written in VB.net

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim watch As New Stopwatch
    watch.Start()

    Dim maxVal As Long = 2000000
    Dim sumOfPrimes As Long = 0
    For i As Integer = 2 To maxVal
        If (isPrime(i) = True) Then
            sumOfPrimes += i
        End If
    Next
    watch.Stop()
    Console.WriteLine(watch.ElapsedMilliseconds)
    Console.WriteLine("The sum of all the prime numbers below " & maxVal & " is " & sumOfPrimes)
End Sub

Function isPrime(ByVal NumToCheck As Integer) As Boolean
    For i As Integer = 2 To (Math.Sqrt(CDbl(NumToCheck)))
        If (NumToCheck Mod i = 0) Then
            Return False
        End If
    Next
    Return True
End Function

VB output:

1643
The sum of all the prime numbers below 2000000 is 142913828922

I feel like there's something obvious that I'm missing, because I really can't see VB.net being faster than C++. Any ideas?

Community
  • 1
  • 1
AndyPerfect
  • 1,180
  • 1
  • 10
  • 25
  • 5
    This is a duplicate of [Why does C# execute Math.Sqrt() more slowly than VB.NET?](http://stackoverflow.com/questions/3025968/why-does-c-execute-math-sqrt-more-slowly-than-vb-net) -- the only difference is C++ instead of C#. – Gabe Aug 09 '10 at 16:48
  • Do you see any changes in performance if you compute the square root outside of the loop? – kbrimington Aug 09 '10 at 16:50
  • Did you compile the C++ version in release mode ? – nos Aug 09 '10 at 16:50
  • My apologies, I would have simply looked at that had I known that this was the problem. But, I took that little calculation out of the loop, and the execution time was reduced to 1.158 =) Thanks a bunch - I'll accept your answer below as soon as the time threshold is reached. – AndyPerfect Aug 09 '10 at 16:55

2 Answers2

8

The VB.Net solution computes the square root once at the beginning of the loop, while C++ (and C and C# and Java and so on) all compute the square root every time through the loop because their looping primitives are defined differently.

Gabe
  • 84,912
  • 12
  • 139
  • 238
6

Your problem is that

For i As Integer = 2 To (Math.Sqrt(CDbl(NumToCheck)))

is not the same as

for (int i = 2; i <= (sqrt((double)NumToCheck)); i++)

VB.Net will evaluate the Math.Sqrt once at the beginning, while c++ has to evaluate it every iteration. The same question already exists somewhere on stackoverflow for C# instead of c++.

josefx
  • 15,506
  • 6
  • 38
  • 63
  • +1. The solution should be to create a local variable just before the loop begins with the Sqrt of the number you're checking. That'll create a more fair comparison between the two languages. – Steve Wortham Aug 09 '10 at 17:01