Skip to content

Instantly share code, notes, and snippets.

@bwedding
Last active May 9, 2020 00:23
Show Gist options
  • Save bwedding/218c2d8e69350556d5423ffccec41721 to your computer and use it in GitHub Desktop.
Save bwedding/218c2d8e69350556d5423ffccec41721 to your computer and use it in GitHub Desktop.
C# Sphere collision performance test with parallel for loop
using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Linq;
namespace collisions_sharp
{
public readonly struct vec3
{
readonly float x, y, z;
public vec3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static vec3 operator +(in vec3 a, in vec3 b)
{
return new vec3(a.x + b.x, a.y + b.y, a.z + b.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static vec3 operator -(in vec3 a, in vec3 b)
{
return new vec3(a.x - b.x, a.y - b.y, a.z - b.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float LenSq()
{
return this.x * this.x + this.y * this.y + this.z * this.z;
}
}
readonly struct sphere
{
readonly vec3 pos;
readonly float r;
public sphere(vec3 pos, float r)
{
this.pos = pos;
this.r = r;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool CollidesWith(in sphere other)
{
float radSum = this.r + other.r;
return (other.pos - this.pos).LenSq() < radSum * radSum;
}
}
class Program
{
static void Main(string[] args)
{
var spheres = new sphere[50000];
using (var f = new StreamReader("spheres.dat"))
{
for (var i = 0; i < 50000; i++)
{
float x = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
float y = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
float z = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
float r = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
spheres[i] = new sphere(new vec3(x, y, z), r);
}
}
var sw = new Stopwatch();
sw.Start();
Parallel.For(0, spheres.Length, ii =>
{
for (var j = ii; j < spheres.Length; j++)
{
if (ii != j && spheres[ii].CollidesWith(spheres[j]))
{
Console.WriteLine("{0} collides with {1}", ii, j);
}
}
});
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.ReadKey();
}
}
}
@bwedding
Copy link
Author

bwedding commented May 9, 2020

Original Code Before Optimization:

using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.Diagnostics;

namespace collisions_sharp
{
struct Vec3
{
float x, y, z;

    public Vec3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public static Vec3 operator +(Vec3 a, Vec3 b)
    {
        return new Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
    }

    public static Vec3 operator -(Vec3 a, Vec3 b)
    {
        return new Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
    }

    public float LenSq()
    {
        return this.x * this.x + this.y * this.y + this.z * this.z;
    }
}

class Sphere
{
    Vec3 pos;
    float r;

    public Sphere(Vec3 pos, float r)
    {
        this.pos = pos;
        this.r = r;
    }

    public bool CollidesWith(Sphere other)
    {
        float radSum = this.r + other.r;
        return (other.pos - this.pos).LenSq() < radSum * radSum;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var spheres = new List<Sphere>();
        using (var f = new StreamReader("spheres.dat"))
        {
            for (var i = 0; i < 50000; i++)
            {
                float x = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
                float y = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
                float z = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
                float r = float.Parse(f.ReadLine(), CultureInfo.InvariantCulture);
                spheres.Add(new Sphere(new Vec3(x, y, z), r));
            }
        }

        var sw = new Stopwatch();
        sw.Start();

        for (var i = 0; i < spheres.Count; i++)
        {
            for (var j = i; j < spheres.Count; j++)
            {
                if (i != j && spheres[i].CollidesWith(spheres[j]))
                {
                    Console.WriteLine("{0} collides with {1}", i, j);
                }
            }
        }

        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);
        Console.ReadKey();
    }
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment