Hello,
I’m trying to make a simple waypoint script to allow an object to visit points of interest
I wonder if anyone can help with this please, it’s driving me crackers?
Given this initial set-up :-
var poiContainer : GameObject;
private var pointsOfInterest : Array;
private var currentPoi : int = 0;
function Start () {
me = transform ;
GetAllPointsOfInterest();
}
function GetAllPointsOfInterest () {
var tempPointsOfInterest : Array = poiContainer.GetComponentsInChildren( Transform );
pointsOfInterest = new Array();
for ( var tempPointsOfInterest : Transform in tempPointsOfInterest ) {
if ( tempPointsOfInterest != poiContainer.transform ) {
pointsOfInterest[ pointsOfInterest.length ] = tempPointsOfInterest;
}
}
}
The above set up works just fine and the variable ‘currentPoi’ is incremented to get the next ‘Point Of Interest’…
HOWEVER - For some reason I’m getting a SERIOUS performance hit (like a reduction to 1 frame per second) when using this line of code (on the iOS device):-
nextPoiVector = Vector3(pointsOfInterest[currentPoi].position.x, me.position.y, pointsOfInterest[currentPoi].position.z);
I believe it must be something to do with the Array, because this line of code, if substituted for the above, works just fine:-
nextPoiVector = Vector3(Random.Range(-100, 100), me.position.y, Random.Range(-100, 100));
Is it really possible that the simple Array look-up could be utterly killing performance?
Anyone know what is going on?
Array is no array its a dictionary style thing.
use [ ] for O(1) array lookup, for example Transform[ ] points = new Transform[10]; or whatever
anything that allows push and pop commonly has a significantly higher lookup than O(1) as dynamically growing datastructures are never O(1) (the hashtable is the only one close to it but as you normally use strings for the keys, the GC will break your neck again on mobile)
and that the code there is troublesome is clear.
Don’t forget: Vector3 is a struct not a class so all lookups there create a “trash vector” that needs to be collected and if nextPoiVector is generated each loop run, thats another trash vector, basically creating 3 trash vectors per loop run
Check out the array documentation for details on why that type of array is slow for lookups, and what the alternatives are.
edit: dreamora beat me to it.
ArrayLists are a little faster than Arrays, and have most of the same abilities. Generic Lists are way faster than either, and still have a dynamic length of the array, but are limited to one type. Built-in arrays are quite a bit faster still, though they are fixed length. So always try to use built-in arrays. If you really need a dynamic length, use generic Lists if you’re just dealing with one type in the array. In some cases it’s feasible to use a dynamic-length array for setting stuff up if you don’t know ahead of time what the length will be, and then convert that to a built-in array for general access.
In this particular case, what’s also causing a hit is that you’re storing Transforms. It would be faster to store the position directly, so you have an array of Vector3s instead of an array of Transforms, although if the transforms are moving then that wouldn’t be feasible of course.
–Eric
Thank you for your speedy replies Dreamora, xomg and Eric5h5 - once again I’m super-impressed by this forum and how helpful you guys are - it’s much appreciated!
I am aware that some Arrays are quicker than others, and my next step was going to be to try using a different one. However what threw me here was the sheer extent of the performance hit when running on the device, ie. my project goes from a comfortable 25fps to less than 1fps when I use the example above!
Eric, my POI objects are in motion so I do need to store their transforms, and look up the position of the current one each frame unfortunately, however, the number of POIs (ie. the array.length) is a known quantity at Start().
I’ll try out the various different ‘types’ of Arrays/Lists suggested above later tonight and report back if it solves the problem I’m seeing, to close the thread.
Thanks again!
Excellent, using a builtin array did the trick!
Cheers.
Garbage collection and allocating dynamic data is always a slow operation, you just don’t notice it very much on a cutting edge pc 