Author Topic: optimize ScriptObject creation?  (Read 1443 times)

This is a bit of a long shot, but is there any way to optimize ScriptObject creation? Currently it's the slowest part of my code:

Code: [Select]
//Gets node at the specified position.
//Grid3DNode object will be created if it does not exist.
//@param vector3F position
//@return Grid3DNode
function Grid3D::getNodeAt(%this, %position)
{
%dif = vectorSub(%position, %this.origin);
%difX = getWord(%dif, 0) - (%this.nExtX >> 1);
%difY = getWord(%dif, 1) - (%this.nExtY >> 1);
%difZ = getWord(%dif, 2) - (%this.nExtZ >> 1);

%x = (%difX / %this.nExtX + 1) >> 0;
%y = (%difY / %this.nExtY + 1) >> 0;
%z = (%difZ / %this.nExtZ + 1) >> 0;

if(!isObject(%this.node[%x, %y, %z]))
{
//Creating this object is the slowest part of the code.
//Unsure how to optimize.
%nPos = vectorAdd(%x * %this.nExtX SPC %y * %this.nExtY SPC %z * %this.nExtZ, %this.origin);
%this.node[%x, %y, %z] = new ScriptObject()
{
class = Grid3DNode;
position = %nPos;
};
%this.add(%this.node[%x, %y, %z]);
}
return %this.node[%x, %y, %z];
}

It looks like my only option is to queue up this function so that it's only called a couple times per tick, but I wanted to check here first. This question is really targeted at those people who've spent a lot of time looking at the engine source.

If all you're storing in the script object is position, then you probably shouldn't be using so many script objects. Why not just set %this.node[%x, %y, %z] to %nPos?

If you have methods on Grid3DNode, convert them to Grid3D methods and add %x, %y, %z or %nPos as parameters.

Other information gets stored later. I'll just use schedules and a queue to spread out the object creation. Not ideal but it will work.

Doesn't seem to be anything that could be optimized in the posted code. Instead of trying to optimize that function, try to reduce the amount of times you're calling that function.

You could create an object pool and not delete these scriptobjects once you no longer need them, then you can quickly re-use them later and set the two variables (assuming you only need them for a certain short time)

Solution: Don't make scriptobjects. They're slow. They always will be slow, in more than one way. For example, all variables in scriptobjects are stored as strings and doing operations on strings and setting variables to strings takes significantly more time than a float or an integer.

I'm not using this method anymore but I'll put it here for whoever wants it.

Code: [Select]
$TSObject::Count = 0;

function TSObject()
{
%idx = $TSObject::Count + 1;
$TSObject::exists[%idx] = 1;
$TSObject::childCount[%idx] = 0;
$TSObject::Count ++;
return %idx;
}

function TSObject::delete(%idx)
{
for(%i = $TSObject::childCount[%idx] - 1; %i >= 0; %i --)
TSObject::delete($TSObject::child[%idx, %i]);
deleteVariables("$TSObject::attr" @ %idx @ "*");
deleteVariables("$TSObject::child" @ %idx @ "*");
deleteVariables("$TSObject::parent" @ %idx);
deleteVariables("$TSObject::exists" @ %idx);
}

function TSObject::exists(%idx)
{
return !!$TSObject::exists[%idx];
}

function TSObject::getAttribute(%idx, %attribute)
{
return $TSObject::attr[%idx, %attribute];
}

function TSObject::setAttribute(%idx, %attribute, %value)
{
return $TSObject::attr[%idx, %attribute] = %value;
}

function TSObject::addChild(%idx, %childIdx)
{
$TSObject::child[%idx, $TSObject::childCount[%idx]] = %childIdx;
$TSObject::childCount[%idx] ++;
TSObject::setParent(%childIdx, %idx);
}

function TSObject::removeChild(%idx, %childIdx)
{
%index = TSObject::getInternalChildIdx(%idx, %childIdx);
if(%index == -1)
return;
for(%i = %index + 1; %i < $TSObject::childCount[%idx]; %i ++)
$TSObject::child[%idx, %i - 1] = $TSObject::child[%idx, %i];
$TSObject::child[%idx, $TSObject::childCount[%idx]] = 0;
$TSObject::childCount[%idx] --;
TSObject::setParent(%childIdx, 0);
}

function TSObject::getInternalChildIdx(%idx, %childIdx)
{
for(%i = 0; %i < $TSObject::childCount[%idx]; %i ++)
{
if($TSObject::child[%idx, %i] == %childIdx)
return %i;
}
return -1;
}

function TSObject::setParent(%this, %idx, %parentIdx)
{
$TSObject::parent[%idx] = %parentIdx;
}
« Last Edit: July 17, 2015, 02:07:55 AM by Greek2me »

instead of doing !!$TSObjectstuff, would $TSObjectstuff | 0 do the same thing?

edit, oh, it's gone now

instead of doing !!$TSObjectstuff, would $TSObjectstuff | 0 do the same thing?

edit, oh, it's gone now

I put it back. Yes, it actually would!

just seeing !!bleh looks really funny to me, but makes sense since you're trying to convert it to true/false from whatever it may be
in cases like this I kind of prefer java's way of handling things

I put it back. Yes, it actually would!
Well, not really. It would just convert it to an integer, not a boolean like you wanted.

true, probably the easiest ways are !!bleh or bleh != 0