C# almost double as fast as VB.NET?
C# code:
using System;
class SpectralNorm
{
// // // // Var Def //
static DateTime startTime;
static DateTime stopTime;
static TimeSpan elapsedTime;
static long elapsedMS;
static void Main(String[] args) {
startTime = DateTime.Now;
int n = 1000;
if (args.Length > 0) n = Int32.Parse(args[0]);
Console.WriteLine("{0:f9}", new SpectralNorm().Approximate(n));
stopTime = DateTime.Now; elapsedTime = stopTime.Subtract(startTime);
elapsedMS = (long)elapsedTime.TotalMilliseconds;
Console.WriteLine("Elapsed Time: {0}", elapsedMS);
Console.ReadLine();
}
double Approximate(int n) {
// create unit vector
double[] u = new double[5000];
for (int i=0; i<n; i++) u
= 1;
// 20 steps of the power method
double[] v = new double[5000];
for (int i=0; i<n; i++) v
= 0;
for (int i=0; i<10; i++) {
MultiplyAtAv(ref n, ref u, ref v);
MultiplyAtAv(ref n, ref v, ref u);
}
// B=AtA A multiplied by A transposed
// v.Bv /(v.v) eigenvalue of v
double vBv = 0, vv = 0;
for (int i=0; i<n; i++) {
vBv += u
*v
;
vv += v
*v
;
}
return Math.Sqrt(vBv/vv);
}
/* return element i,j of infinite matrix A */
double A(ref int i, ref int j){
return 1.0/((i+j)*(i+j+1)/2 +i+1);
}
/* multiply vector v by matrix A */
void MultiplyAv(ref int n, ref double[] v, ref double[] Av){
for (int i=0; i<n; i++){
Av
= 0;
for (int j=0; j<n; j++) Av
+= A(ref i, ref j)*v[j];
}
}
/* multiply vector v by matrix A transposed */
void MultiplyAtv(ref int n, ref double[] v, ref double[] Atv){
for (int i=0;i<n;i++){
Atv
= 0;
for (int j=0; j<n; j++) Atv
+= A(ref j,ref i)*v[j];
}
}
/* multiply vector v by matrix A and then by matrix A transposed */
void MultiplyAtAv(ref int n, ref double[] v, ref double[] AtAv){
double[] u = new double[5000];
MultiplyAv(ref n, ref v, ref u);
MultiplyAtv(ref n, ref u, ref AtAv);
}
}
and now for VB:
Option Strict On
Imports System
Class SpectralNorm
Shared startTime As DateTime
Shared stopTime As DateTime
Shared elapsedTime As TimeSpan
Shared elapsedMS As Long
Public Shared Sub Main(ByVal args As String())
startTime = DateTime.Now
Dim n As Integer = 1000
If args.Length > 0 Then
n = Int32.Parse(args(0))
End If
stopTime = DateTime.Now : elapsedTime = stopTime.Subtract(startTime)
elapsedMS = CLng(elapsedTime.TotalMilliseconds)
Console.WriteLine("{0:f9}", New SpectralNorm().Approximate(n))
Console.WriteLine("Time taken: {0}", elapsedMS)
End Sub
Private Function Approximate(ByVal n As Integer) As Double
' create unit vector
Dim u(5000) As Double
For i As Integer = 0 To n - 1
u(i) = 1
Next
' 20 steps of the power method
Dim v(5000) As Double
For i As Integer = 0 To n - 1
v(i) = 0
Next
For i As Integer = 0 To 9
MultiplyAtAv(n, u, v)
MultiplyAtAv(n, v, u)
Next
' B=AtA A multiplied by A transposed
' v.Bv /(v.v) eigenvalue of v
Dim vBv As Double = 0, vv As Double = 0
For i As Integer = 0 To n - 1
vBv += u(i) * v(i)
vv += v(i) * v(i)
Next
Return Math.Sqrt(vBv / vv)
End Function
' return element i,j of infinite matrix A
Private Function A(ByRef i As Integer, ByRef j As Integer) As Double
Return 1 / ((i + j) * (i + j + 1) / 2 + i + 1)
End Function
' multiply vector v by matrix A
Private Sub MultiplyAv(ByRef n As Integer, ByRef v As Double(), ByRef Av As Double())
For i As Integer = 0 To n - 1
Av(i) = 0
For j As Integer = 0 To n - 1
Av(i) += A(i, j) * v(j)
Next
Next
End Sub
' multiply vector v by matrix A transposed
Private Sub MultiplyAtv(ByRef n As Integer, ByRef v As Double(), ByRef Atv As Double())
For i As Integer = 0 To n - 1
Atv(i) = 0
For j As Integer = 0 To n - 1
Atv(i) += A(j, i) * v(j)
Next
Next
End Sub
' multiply vector v by matrix A and then by matrix A transposed
Private Sub MultiplyAtAv(ByRef n As Integer, ByRef v As Double(), ByRef AtAv As Double())
Dim u(5000) As Double
MultiplyAv(n, v, u)
MultiplyAtv(n, u, AtAv)
End Sub
End Class
Now, guess what? Everything on release and optimized, on my AXP, the C# example is a freaking 100 % faster than the VB.NET one!! WTF, Microsoft? This is absolutely ridiculous! I mean, 5-10 %, no problem, but this?!!

