I have posted similar threads before when I have found deficiencies in core math in Unity (like Mathf).
Here is another one.
According to the monodevelop .dll reflector, this is the implementation for Bounds.Intersect
using System;
public bool Intersects (Bounds bounds)
{
return this.min.x <= bounds.max.x this.max.x >= bounds.min.x this.min.y <= bounds.max.y this.max.y >= bounds.min.y this.min.z <= bounds.max.z this.max.z >= bounds.min.z;
}
Note that it gets bounds.max and min A LOT. These are properties which involve a Vector3 addition. So this piece of code currently uses 36 additions and also 12 copies of Vector3’s (properties must return copies). Also the fact that it calls properties is in itself overhead at least on 32bit (64bit mono does seem to optimize for that better, only a very very small overhead compared to direct field access). It could use only 12 additions and no copies or property accesses if implemented correctly. Also, I doubt the JIT is smart enough to optimize this, it would have to figure out that it is only using the .x (or .y or .z) field, and then track the addition operator and see that it actually only need to add the .x fields to get the resulting .x field. Especially since the JIT doesn’t even properly inline simple getter properties in 32bit (including the unity editor).
I am noting this here because when profiling, I found that Bounds.Intersect took 2.2% of the CPU time, an unreasonably high percentage for what it was doing.
Also, the Bounds.max and min getters in turn call the center and extents properties, not the fields, even though the code has access to those private fields. On 32bit (and in the unity editor) this will cause slowdowns.
Bounds.size is however well behaved and uses the fields directly.
Please Unity guys, fix these kinds of things in the API.
Unity Version: 4.2.0b4
Operating System: OS X (10.7.4)
[EDIT]
Profiling it, it seems like I can with very simple code, make it run 30% faster.
private bool Intersects (Bounds b1, Bounds b2) {
Vector3 min1 = b1.min;
Vector3 max1 = b1.max;
Vector3 min2 = b2.min;
Vector3 max2 = b2.max;
return min1.x <= max2.x max1.x >= min2.x min1.y <= max2.y max1.y >= min2.y min1.z <= max2.z max1.z >= min2.z;
}
Even though the above code has several things slowing it down. It needs to take another parameter, which requires a 24 byte copy of the struct, and it must store the max and min values as variables instead of calculating them directly in the expression since it does not have direct access to the fields. Also it must use the getters for the min and max values for the same reason.
U bounds 3085.2 ms avg: 308.52 ms avg mem: 0 bytes
U2 bounds 2193.8 ms avg: 219.38 ms avg mem: 0 bytes
Profiling code: using System;using Pathfinding;using System.Collections.Generic;using Unit - Pastebin.com
The Profile class simply holds a System.Diagnostics.Stopwatch and also queries System.GC for the memory usage.