Yes, it indeed appears as if the majority of the execution time goes into building the NativeArray with all the tile coordinates, while the job operating on said array only takes a tiny fraction of the computational time.
But that array does not even contain very useful data. It's really just a consecutive list of all the coordinates within a large rectangle. Some things you could try are:
- Don't parallelize per-tile, parallelize per-row. Create a
NativeArray<int>
of the row numbers you want to check, and then have the Execute-function perform a for-loop over the tiles from start to end of the row. This still gives you 100 units of work for a 100x100 selection. Still more than enough granularity for letting the engine distribute the load on multiple cores in an efficient manner. - Create a permanent NativeArray for all tiles on the map which you create once (
Allocator.Persistent
). Then useNativeSlice
s to tell the job system which tiles you want checked. - Use another (non-parallel) job to build the
UncheckedNodes
NativeArray. A burst-compiled job might be able to do that more efficiently than regular C# code. Then schedule theReallyToughParallelJob
with the array-building job as a dependency. - (probably the best solution) Don't use the array at all. Replace it with these fields to the job which tell the job the area it's supposed to iteratateiterate:
[ReadOnly] public float xStart;
[ReadOnly] public float width;
[ReadOnly] public float yStart;
// height is implied by the iteration count you pass when you schedule the job
And then calculate the tile coordinates of the current tile in the Execute method:
x = index % width + xStart;
y = index / width + yStart;