ThreatSourceLibaray/ThreatSource.Tests/Utils/Vector3DPerformanceTests.cs

147 lines
6.9 KiB
C#

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using ThreatSource.Utils; // Assuming Vector3D is here, adjust if necessary
using System.Collections.Generic;
using System;
namespace ThreatSource.Tests.Utils
{
[TestClass]
public class Vector3DPerformanceTests
{
private const int Iterations = 1000000; // Number of iterations for performance testing
private Vector3D CreateVector(double i)
{
// Helper to create slightly different vectors
return new Vector3D(i, i + 1.5, i * 0.8);
}
[TestMethod]
public void Baseline_Vector3D_Class_Performance()
{
// This test assumes Vector3D is currently a CLASS.
// We will run this once, record results, then change Vector3D to struct and run again.
Stopwatch stopwatch = new Stopwatch();
List<Vector3D> vectors = new List<Vector3D>(Iterations);
double totalMagnitude = 0;
Random rand = new Random(123); // Seeded for reproducibility
// --- Test 1: Creation Performance ---
stopwatch.Start();
for (int i = 0; i < Iterations; i++)
{
vectors.Add(CreateVector(i * rand.NextDouble()));
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] Creation of {Iterations} Vector3D instances: {stopwatch.ElapsedMilliseconds} ms");
long creationTime = stopwatch.ElapsedMilliseconds;
// Ensure vectors are used to prevent over-optimization by compiler
if (vectors.Count == 0) throw new Exception("Vector list empty after creation.");
Vector3D tempVector1 = CreateVector(10.1);
Vector3D tempVector2 = CreateVector(20.2);
// --- Test 2: Addition Performance ---
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
tempVector1 = tempVector1 + vectors[i];
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Additions: {stopwatch.ElapsedMilliseconds} ms");
long additionTime = stopwatch.ElapsedMilliseconds;
// --- Test 3: Subtraction Performance ---
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
tempVector1 = tempVector1 - vectors[i];
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Subtractions: {stopwatch.ElapsedMilliseconds} ms");
long subtractionTime = stopwatch.ElapsedMilliseconds;
// --- Test 4: Scalar Multiplication Performance ---
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
tempVector1 = vectors[i] * 2.5;
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Scalar Multiplications: {stopwatch.ElapsedMilliseconds} ms");
long scalarMultTime = stopwatch.ElapsedMilliseconds;
// --- Test 5: Dot Product Performance ---
double dotProductSum = 0;
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
dotProductSum += Vector3D.DotProduct(vectors[i], tempVector2);
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Dot Products: {stopwatch.ElapsedMilliseconds} ms");
long dotProductTime = stopwatch.ElapsedMilliseconds;
// --- Test 6: Cross Product Performance ---
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
tempVector1 = Vector3D.CrossProduct(vectors[i], tempVector2);
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Cross Products: {stopwatch.ElapsedMilliseconds} ms");
long crossProductTime = stopwatch.ElapsedMilliseconds;
// --- Test 7: Magnitude Performance ---
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
totalMagnitude += vectors[i].Magnitude();
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Magnitudes: {stopwatch.ElapsedMilliseconds} ms");
long magnitudeTime = stopwatch.ElapsedMilliseconds;
// --- Test 8: Normalization Performance ---
stopwatch.Restart();
for (int i = 0; i < Iterations; i++)
{
// Avoid normalizing zero vectors which might throw exceptions or return NaN
if (vectors[i].MagnitudeSquared() > 0.00001)
{
tempVector1 = vectors[i].Normalize();
}
else
{
tempVector1 = vectors[i]; // Assign to ensure work is done
}
}
stopwatch.Stop();
Console.WriteLine($"[Baseline Class] {Iterations} Vector3D Normalizations: {stopwatch.ElapsedMilliseconds} ms");
long normalizeTime = stopwatch.ElapsedMilliseconds;
Console.WriteLine($"[Baseline Class] Total magnitude sum (to prevent optimization): {totalMagnitude}");
Console.WriteLine($"[Baseline Class] Final tempVector1 (to prevent optimization): {tempVector1}");
Console.WriteLine($"[Baseline Class] Final dotProductSum (to prevent optimization): {dotProductSum}");
// For MSTest, Assert.Inconclusive can be used to output results without failing the test.
// Alternatively, a simple Console.WriteLine at the end of the test with a summary is also fine
// if the test isn't meant to pass/fail based on performance but just to gather data.
// For this baseline, we'll use Assert.Inconclusive to clearly mark the output in test results.
string resultSummary = $"Baseline performance (Vector3D as CLASS):\n" +
$"Creation: {creationTime} ms\n" +
$"Addition: {additionTime} ms\n" +
$"Subtraction: {subtractionTime} ms\n" +
$"Scalar Mult: {scalarMultTime} ms\n" +
$"Dot Product: {dotProductTime} ms\n" +
$"Cross Product: {crossProductTime} ms\n" +
$"Magnitude: {magnitudeTime} ms\n" +
$"Normalization: {normalizeTime} ms";
Console.WriteLine(resultSummary); // Ensure it's also printed to console output for easy viewing
Assert.Inconclusive(resultSummary); // Marks test as inconclusive and shows message in test explorer
}
}
}