For the test I used my own built OpenTK, a own built Sharp3D Dll and a separate Dll-project for Potters Vector3 class. I converted Potters Vector3 to float.
Here are the results for the release build:
Testing 30.000.000 iterations.OpenTK Add Func - 00:00:00.3910775OpenTK Add Op - 00:00:01.3609497Sharp3 Add Func - 00:00:01.0324446Sharp3 Add Op - 00:00:01.6581686Potter Add - 00:00:01.6894548OpenTK Sub Func - 00:00:00.3754344OpenTK Sub Op - 00:00:01.3609497Sharp3 Sub Func - 00:00:01.0480877Sharp3 Sub Op - 00:00:01.6738117Potter Sub - 00:00:01.6581686OpenTK Mul Scalar Func - 00:00:00.3597913OpenTK Mul Scalar Op - 00:00:01.2983773Sharp3 Mul Scalar Func - 00:00:01.0637308Sharp3 Mul Scalar Op - 00:00:01.7676703Potter Mul Scalar - 00:00:01.5643100OpenTK Div Scalar Func - 00:00:00.5005792OpenTK Div Scalar Op - 00:00:01.2670911Sharp3 Div Scalar Func - 00:00:01.7676703Sharp3 Div Scalar Op - 00:00:02.3621081Potter Div Scalar - 00:00:02.3777512OpenTK Dot - 00:00:00.9855153Sharp3 Dot - 00:00:01.0011584Potter Dot - 00:00:01.2201618OpenTK Cross Copy - 00:00:01.5799531OpenTK Cross Ref - 00:00:00.4380068Sharp3 Cross - 00:00:01.7363841Potter Cross - 00:00:01.8615289OpenTK Length - 00:00:00.7821550Sharp3 Length - 00:00:00.7821550Potter Length - 00:00:04.2082447OpenTK Length Squared - 00:00:00.3754632Sharp3 Length Squared - 00:00:00.3598189OpenTK Normalize - 00:00:02.0024704Sharp3 Normalize - 00:00:02.7533968Potter Normalize - 00:00:10.3252380OpenTK Normalize Fast - 00:00:02.1589134
It seems that the methods from OpenTK are the fastest. It's hardly surprising that passing the arguments by ref is significant faster than the usually copy pass.
Here is the complete Source code for my performance test:
using System;using System.Collections.Generic;using System.Text;namespace PerfTest_Vector3{ class Program { private delegate void TestDel(); static void Main(string[] args) { // Init. Random rand = new Random(); float scalar = (float)rand.NextDouble(); float x1 = (float)rand.NextDouble(); float y1 = (float)rand.NextDouble(); float z1 = (float)rand.NextDouble(); float x2 = (float)rand.NextDouble(); float y2 = (float)rand.NextDouble(); float z2 = (float)rand.NextDouble(); OpenTK.Math.Vector3 tk1 = new OpenTK.Math.Vector3(x1, y1, z1); OpenTK.Math.Vector3 tk2 = new OpenTK.Math.Vector3(x2, y2, z2); OpenTK.Math.Vector3 tk3 = new OpenTK.Math.Vector3(); Sharp3D.Math.Core.Vector3F sh1 = new Sharp3D.Math.Core.Vector3F(x1, y1, z1); Sharp3D.Math.Core.Vector3F sh2 = new Sharp3D.Math.Core.Vector3F(x2, y2, z2); Sharp3D.Math.Core.Vector3F sh3 = new Sharp3D.Math.Core.Vector3F(); Vector3F rp1 = new Vector3F(x1, y1, z1); Vector3F rp2 = new Vector3F(x2, y2, z2); Vector3F rp3 = new Vector3F(); const int iters = 30000000; // Test Console.WriteLine("Testing {0:n} iterations.", iters); Console.WriteLine(); // Test Add Test("OpenTK Add Func ", iters, delegate() { OpenTK.Math.Vector3.Add(ref tk1, ref tk2, out tk3); }); Test("OpenTK Add Op ", iters, delegate() { tk3 = tk1 + tk2; }); Test("Sharp3 Add Func ", iters, delegate() { Sharp3D.Math.Core.Vector3F.Add(sh1, sh2, ref sh3); }); Test("Sharp3 Add Op ", iters, delegate() { sh3 = sh1 + sh2; }); Test("Potter Add ", iters, delegate() { rp3 = rp1 + rp2; }); Console.WriteLine(); // Test Sub Test("OpenTK Sub Func ", iters, delegate() { OpenTK.Math.Vector3.Sub(ref tk1, ref tk2, out tk3); }); Test("OpenTK Sub Op ", iters, delegate() { tk3 = tk1 - tk2; }); Test("Sharp3 Sub Func ", iters, delegate() { Sharp3D.Math.Core.Vector3F.Subtract(sh1, sh2, ref sh3); }); Test("Sharp3 Sub Op ", iters, delegate() { sh3 = sh1 - sh2; }); Test("Potter Sub ", iters, delegate() { rp3 = rp1 - rp2; }); Console.WriteLine(); // Test Mul Scalar Test("OpenTK Mul Scalar Func ", iters, delegate() { OpenTK.Math.Vector3.Mult(ref tk1, scalar, out tk3); }); Test("OpenTK Mul Scalar Op ", iters, delegate() { tk3 = tk1 * scalar; }); Test("Sharp3 Mul Scalar Func ", iters, delegate() { Sharp3D.Math.Core.Vector3F.Multiply(sh1, scalar, ref sh3); }); Test("Sharp3 Mul Scalar Op ", iters, delegate() { sh3 = sh1 * scalar; }); Test("Potter Mul Scalar ", iters, delegate() { rp3 = rp1 * scalar; }); Console.WriteLine(); // Test Div Scalar Test("OpenTK Div Scalar Func ", iters, delegate() { OpenTK.Math.Vector3.Div(ref tk1, scalar, out tk3); }); Test("OpenTK Div Scalar Op ", iters, delegate() { tk3 = tk1 / scalar; }); Test("Sharp3 Div Scalar Func ", iters, delegate() { Sharp3D.Math.Core.Vector3F.Divide(sh1, scalar, ref sh3); }); Test("Sharp3 Div Scalar Op ", iters, delegate() { sh3 = sh1 / scalar; }); Test("Potter Div Scalar ", iters, delegate() { rp3 = rp1 / scalar; }); Console.WriteLine(); // Test Dot Test("OpenTK Dot ", iters, delegate() { scalar = OpenTK.Math.Vector3.Dot(tk1, tk2); }); Test("Sharp3 Dot ", iters, delegate() { scalar = Sharp3D.Math.Core.Vector3F.DotProduct(sh1, sh2); }); Test("Potter Dot ", iters, delegate() { scalar = rp1.DotProduct(rp2); }); Console.WriteLine(); // Test Cross Test("OpenTK Cross Copy ", iters, delegate() { tk3 = OpenTK.Math.Vector3.Cross(tk1, tk2); }); Test("OpenTK Cross Ref ", iters, delegate() { OpenTK.Math.Vector3.Cross(ref tk1, ref tk2, out tk3); }); Test("Sharp3 Cross ", iters, delegate() { sh3 = Sharp3D.Math.Core.Vector3F.CrossProduct(sh1, sh2); }); Test("Potter Cross ", iters, delegate() { rp3 = rp1.CrossProduct(rp2); }); Console.WriteLine(); // Test Length Test("OpenTK Length ", iters, delegate() { scalar = tk1.Length; }); Test("Sharp3 Length ", iters, delegate() { scalar = sh1.GetLength(); }); Test("Potter Length ", iters, delegate() { scalar = rp1.Magnitude; }); Console.WriteLine(); // Test Length Squared Test("OpenTK Length Squared ", iters, delegate() { scalar = tk1.LengthSquared; }); Test("Sharp3 Length Squared ", iters, delegate() { scalar = sh1.GetLengthSquared(); }); Console.WriteLine(); // Test Normalize Test("OpenTK Normalize ", iters, delegate() { tk1.Normalize(); }); Test("Sharp3 Normalize ", iters, delegate() { sh1.Normalize(); }); Test("Potter Normalize ", iters, delegate() { rp1.Normalize(); }); Console.WriteLine(); // Test Normalize Fast Test("OpenTK Normalize Fast ", iters, delegate() { tk1.NormalizeFast(); }); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Finished"); Console.ReadLine(); } private static void Test(string prefix, int iters, TestDel testFunc) { DateTime start = DateTime.Now; for (int i = 0; i < iters; i++) { testFunc(); } TimeSpan span = DateTime.Now - start; Console.WriteLine("{0} - {1}", prefix, span); } }}