- Home /
How and when to use a JS Array over BuiltIn Array
I attached the project file Unity3d42_test.zip 200KB (Unity 4.3.1f1).
Description of a project: We simulate a life cicle of a plant (or a life form). Life starts, grows, matures, reproduces (x times), dies. This goes forever or until there is no plant left on the grid.
See two main scripts: Game.js LifeForm.js
My questions in regards to arrays:
If I increase the array size beyond 32*32 (in fact 1024 items) the "Main thread" time ratio to "Renderer time" increases out of proportions.
Did I use the arrays in a correct way as they were intended to be used in Unity?
Game.js: function LifeFormDeliver() How costly is JS array conversion to BuiltIn arrays?
Would it be faster (for a big array) to manualy copy the array instead of assigning it directly to a variable?
var area_free: Vector3[];
var area_free_array = new Array();
area_free = area_free_array.ToBuiltin(Vector3) as Vector3[];
Thank you in advance.
$$anonymous$$ay I ask why you opt for JS array over builtin?
Because the JS Array is dynamic and I can add items to it without knowing how long the array would be. The length is kind of the problem here. But I guess I could do it with fixed size arrays. Save on reallocation. If I set array to max items this would result in greater memory usage. That is the dillema here.
You are now able to resize Builtin arrays with
System.Array.Resize.(ArrayName, Size);
You probably don't want to do this each call though :D
@meat5000 That's not really resizing - it implicitly creates a new array and copies it over. If you need a dynamic data structure, use a generic List. I'd keep away from JS Arrays or non-generic Lists, though.
Answer by Statement · Dec 08, 2013 at 08:56 PM
Use a built in array when you know the size in advance or don't need to resize it very often.
Use a built in array if you know for a fact that Array/List/Whatever is slowing you down.
ArrayList
had some bad reputation, likely because of overhead casting objects when accessing it.Use
List.< T >
in favour ofArrayList
as it accomplishes the same thing but is type safe and doesn't cast.
Apologies for not giving your complete project a lot of attention; the script is large and the variable names are crypic like "b", "bt" and "bc" which just makes it hard to figure out what your code is actually trying to achieve, so I gave up.
Built in arrays (Vector3[]) is faster than using arrays. However, they are not a lot faster and the general reason your scripts become slower with increasing sizes are generally:
The algorithm has a poor time complexity.
The data structure thrashes cache.
If your algorithm has poor time complexity, you may want to look into figuring out a different way of managing your simulation. For example, if you were doing something like:
for (..)
for (..)
Then you probably are looking at an algorithm that has a time complexity of O(N^2). This means that if you increase the number of items from 5 to 10, it's not 2 times as slow. It's 25 (5*5) ops vs 100 (10*10) ops, and it's 4 times as slow.
Another issue can be cache thrashing and is a bit more complicated since you need to understand how the CPU cache lines and cache policy works. But generally you can think of your memory as one big line of data (bear with me). A cache line is like a segment of your data line. If you can avoid leaving the cache line, the CPU will work faster since it doesn't have to pull new data from RAM. I won't get into details, but you can start looking at a Z-Order curve or a "Morton Curve" on wiki. This particular memory mapping is good when you access neighbors in a 2D grid (perhaps you are doing the same?) and is applicable when you want to "for a given point, check the neighboring points for something" because the morton curve will remap your indices to lie in a cache line and not outside cache lines, for the most cases. I used this myself when I was doing a voxel engine and the results was about 3x lookup speed for my particular set of operations I did with each voxel (as opposed to just using a simple array with 3 ranks (`float[,,]`).
I also discussed speed difference of List and a built in array earlier, which you can read here.
Also, I just noticed you do the calc in fixed update. Why? Does it respond to physics? Try moving it to Update, or you will suffer from Unity trying to "catch up the physics sims due to lag" and the lag is actually caused inside your FixedUpdate. So it becomes a bad spiral of performance issues.
Also looking at your Statistics window, you have a load of Draw calls. Try turning the visuals off and see if the problem really is your algorithm or something else. If you got access to Unity Pro, use the Profiler to narrow down on what exactly is using your time. (Just disable the camera)
Thank you for you time. I played around Update, FixedUpdate (Fixed timestep, $$anonymous$$aximum allowed timestep). FixedUpdate does not slow down the simulation in principle. But point taken. This was in general not a good idea. I know why. Just experimenting how Unity works. - Unity free.
I turned off the camera. Renderer 0%. CPU time and frame rate stays about the same.
In my opinion, unless your game is Physics heavy, use of FixedUpdate should be fine.
In my (Android) project FixedUpdate is very heavy, but I have a small amount of physics and with a FixedTimeStep adjustment it's as smooth as silk and feels a lot more responsive than when I used Update, even on older single core devices with A2.3.1.
So overuse of FixedUpdate is ill advised and this is sound advice but it is also very project dependent.
The problematic code: Tries to detect items that are ready to activate surrounding items "lifeForm.reproduction_ready".
LifeFormGetArea(lifeForm.position, lifeForm.reproduction_range); // get all possible surrounding elements based on Square area size of lifeForm.reproduction_range around lifeForm element.
Then I detect which positions in this area are free for expansion. (lifeFormTmp.energy == 0) // this means it's empty
And finally (a bit criptic) I randomly select free (open) positions and place a new life form. How many depends on lifeForm.reproduction_size.
LifeFormGenerate(lifeFormTmp); lifeForm.Birth();
Thank you for now. I will study Z-order and other wiki docs on this topic. Will let you know.
Answer by Eric5h5 · Dec 08, 2013 at 10:38 PM
You would never, ever use a JS Array. Similarly, ArrayList is obsolete and should be avoided. Use a generic List instead if the array is going to change size; it does everything JS Array and ArrayList do except faster/better.
Your answer
![](https://koobas.hobune.stream/wayback/20220613123727im_/https://answers.unity.com/themes/thub/images/avi.jpg)