using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class BurstSmallestDistance : MonoBehaviour
{
public int
cellSize = 1,
iterations = 64,
batchSize = 32;
private void Start()
{
var test = new BurstDistance();
BurstDistance.batchSize = batchSize;
List<BurstDistance.PotentialCell> somePotentialCells = new(cellSize);
BurstDistance.PotentialCell[] somePotentialCellsArr = new BurstDistance.PotentialCell[cellSize];
for (int i = 0; i < cellSize; i++)
{
var rand = UnityEngine.Random.insideUnitSphere * 100f;
somePotentialCells.Add(new BurstDistance.PotentialCell(rand));
somePotentialCellsArr[i] = new BurstDistance.PotentialCell(rand);
}
Debug.Log("\nCells: " + cellSize);
BurstDistance.PotentialCell cell;
double us;
test.GetBestConnectingCell(float3.zero, math.float3(50, 50, 50), somePotentialCells, out cell);
test.GetBestConnectingCellSThread(float3.zero, math.float3(50, 50, 50), somePotentialCells, out cell);
test.GetBestConnectingCellMThread(float3.zero, math.float3(50, 50, 50), somePotentialCells, out cell);
Stopwatch sw = new Stopwatch();
sw.Restart();
sw.Stop();
sw.Restart();
for (int i = 0; i < iterations; i++)
test.GetBestConnectingCell(float3.zero, math.float3(50, 50, 50), somePotentialCells, out cell);
sw.Stop();
us = 1000.0 * 1000 * sw.ElapsedTicks / Stopwatch.Frequency;
Debug.Log("List\nCells ForEach [Avg Ticks]: " + us / iterations);
sw.Restart();
for (int i = 0; i < iterations; i++)
test.GetBestConnectingCellSThread(float3.zero, math.float3(50, 50, 50), somePotentialCells, out cell);
sw.Stop();
us = 1000.0 * 1000 * sw.ElapsedTicks / Stopwatch.Frequency;
Debug.Log("\nCells SThread [Avg Ticks]: " + us / iterations);
sw.Restart();
for (int i = 0; i < iterations; i++)
test.GetBestConnectingCellMThread(float3.zero, math.float3(50, 50, 50), somePotentialCells, out cell);
sw.Stop();
us = 1000.0 * 1000 * sw.ElapsedTicks / Stopwatch.Frequency;
Debug.Log("\nCells MThread [Avg Ticks]: " + us / iterations);
sw.Restart();
for (int i = 0; i < iterations; i++)
test.GetBestConnectingCell(float3.zero, math.float3(50, 50, 50), somePotentialCellsArr, out cell);
sw.Stop();
us = 1000.0 * 1000 * sw.ElapsedTicks / Stopwatch.Frequency;
Debug.Log("Array\nCells ForEach [Avg Ticks]: " + us / iterations);
sw.Restart();
for (int i = 0; i < iterations; i++)
test.GetBestConnectingCellSThread(float3.zero, math.float3(50, 50, 50), somePotentialCellsArr, out cell);
sw.Stop();
us = 1000.0 * 1000 * sw.ElapsedTicks / Stopwatch.Frequency;
Debug.Log("\nCells SThread [Avg Ticks]: " + us / iterations);
sw.Restart();
for (int i = 0; i < iterations; i++)
test.GetBestConnectingCellMThread(float3.zero, math.float3(50, 50, 50), somePotentialCellsArr, out cell);
sw.Stop();
us = 1000.0 * 1000 * sw.ElapsedTicks / Stopwatch.Frequency;
Debug.Log("\nCells MThread [Avg Ticks]: " + us / iterations);
}
}
public class BurstDistance
{
public static int batchSize = 8;
public struct PotentialCell
{
public float3 coordinate;
public PotentialCell(float3 coord)
{
coordinate = coord;
}
}
[BurstCompile(CompileSynchronously = true)]
public void GetBestConnectingCell(float3 origin, float3 terminus, in List<PotentialCell> potentialCells, out PotentialCell cell)
{
cell = potentialCells[0];
var lowestCost = float.MaxValue;
foreach (PotentialCell item in potentialCells)
{
float cost = math.distance(origin, item.coordinate) + math.distance(terminus, item.coordinate);
if (cost < lowestCost)
{
cell = item;
lowestCost = cost;
}
}
}
[BurstCompile(CompileSynchronously = true)]
public void GetBestConnectingCell(float3 origin, float3 terminus, in PotentialCell[] potentialCells, out PotentialCell cell)
{
cell = potentialCells[0];
var lowestCost = float.MaxValue;
for (int i = 0; i < potentialCells.Length; i++)
{
float cost = math.distance(origin, potentialCells[i].coordinate) + math.distance(terminus, potentialCells[i].coordinate);
if (cost < lowestCost)
{
cell = potentialCells[i];
lowestCost = cost;
}
}
}
[BurstCompile(CompileSynchronously = true)]
public void GetBestConnectingCellSThread(float3 origin, float3 terminus, in List<PotentialCell> potentialCells, out PotentialCell cell)
{
//Setup temp data for the jobs to process. Will be disposed automatically due to 'using'
using var input = new NativeArray<PotentialCell>(potentialCells.ToArray(), Allocator.TempJob);
using var lowestCost = new NativeReference<float>(float.MaxValue, Allocator.TempJob);
using var lowestIndex = new NativeReference<int>(int.MaxValue, Allocator.TempJob);
//Build the job
var evaluateConnectionOriginJob = new EvaluateConnectionOriginJob
{
StartPoint = origin,
EndPoint = terminus,
Input = input,
lowestCost = lowestCost,
lowestIndex = lowestIndex
};
//Schedule the job single threaded
evaluateConnectionOriginJob.Run(potentialCells.Count);
//Return result
cell = input[evaluateConnectionOriginJob.lowestIndex.Value];
}
[BurstCompile(CompileSynchronously = true)]
public void GetBestConnectingCellSThread(float3 origin, float3 terminus, in PotentialCell[] potentialCells, out PotentialCell cell)
{
//Setup temp data for the jobs to process. Will be disposed automatically due to 'using'
using var input = new NativeArray<PotentialCell>(potentialCells, Allocator.TempJob);
using var lowestCost = new NativeReference<float>(float.MaxValue, Allocator.TempJob);
using var lowestIndex = new NativeReference<int>(int.MaxValue, Allocator.TempJob);
//Build the job
var evaluateConnectionOriginJob = new EvaluateConnectionOriginJob
{
StartPoint = origin,
EndPoint = terminus,
Input = input,
lowestCost = lowestCost,
lowestIndex = lowestIndex
};
//Schedule the job single threaded
evaluateConnectionOriginJob.Run(potentialCells.Length);
//Return result
cell = input[evaluateConnectionOriginJob.lowestIndex.Value];
}
[BurstCompile(CompileSynchronously = true)]
public void GetBestConnectingCellMThread(float3 origin, float3 terminus, in List<PotentialCell> potentialCells, out PotentialCell cell)
{
//Setup temp data for the jobs to process. Will be disposed automatically due to 'using'
using var input = new NativeArray<PotentialCell>(potentialCells.ToArray(), Allocator.TempJob);
using var lowestCost = new NativeReference<float>(float.MaxValue, Allocator.TempJob);
using var lowestIndex = new NativeReference<int>(int.MaxValue, Allocator.TempJob);
//Build the job
var evaluateConnectionOriginJob = new EvaluateConnectionOriginJob
{
StartPoint = origin,
EndPoint = terminus,
Input = input,
lowestCost = lowestCost,
lowestIndex = lowestIndex
};
// Schedule the job multi-threaded
evaluateConnectionOriginJob.Schedule(potentialCells.Count, batchSize).Complete();
//Return result
cell = input[evaluateConnectionOriginJob.lowestIndex.Value];
}
[BurstCompile(CompileSynchronously = true)]
public void GetBestConnectingCellMThread(float3 origin, float3 terminus, in PotentialCell[] potentialCells, out PotentialCell cell)
{
//Setup temp data for the jobs to process. Will be disposed automatically due to 'using'
using var input = new NativeArray<PotentialCell>(potentialCells, Allocator.TempJob);
using var lowestCost = new NativeReference<float>(float.MaxValue, Allocator.TempJob);
using var lowestIndex = new NativeReference<int>(int.MaxValue, Allocator.TempJob);
//Build the job
var evaluateConnectionOriginJob = new EvaluateConnectionOriginJob
{
StartPoint = origin,
EndPoint = terminus,
Input = input,
lowestCost = lowestCost,
lowestIndex = lowestIndex
};
// Schedule the job multi-threaded
evaluateConnectionOriginJob.Schedule(potentialCells.Length, batchSize).Complete();
//Return result
cell = input[evaluateConnectionOriginJob.lowestIndex.Value];
}
[BurstCompile(CompileSynchronously = true)]
public struct EvaluateConnectionOriginJob : IJobParallelFor
{
[ReadOnly] public float3 StartPoint;
[ReadOnly] public float3 EndPoint;
[ReadOnly] public NativeArray<PotentialCell> Input;
[NativeDisableParallelForRestriction]
public NativeReference<float> lowestCost;
[NativeDisableParallelForRestriction]
public NativeReference<int> lowestIndex;
public void Execute(int i)
{
var coord = Input[i].coordinate;
float cost = math.distance(StartPoint, coord) + math.distance(EndPoint, coord);
if (cost < lowestCost.Value)
{
lowestCost.Value = cost;
lowestIndex.Value = i;
}
}
}
}