Game Development Community

is a for loop in C++ faster then torqueScript?

by Mike Moore · in iTorque 2D · 10/16/2009 (6:52 pm) · 15 replies

Hello everyone,

I´m wondering if, talking about memory usage, a for loop in C++ takes less memory and time then using torque script.
If so, it is possible to implement a way to run the C++ for loop being called from a torque script? If this helps to speed up scripts it will be great to have some example since I don´t have experience with C++.
Thanks

Mike

#1
10/16/2009 (7:06 pm)
A function with a loop in it will be faster when converted to C++ from a TorqueScript function. Sometimes amazingly so. It's better to do heavy calculation loops in C++ and get the results by exposing it as a TS function. You'll need to dig into C++ proper, though, so there's no easy fix-all solution normally.

Tell us what you need to do, and perhaps somebody can come up with a snippet of code :)
(Making a new script function in C++ isn't terribly hard, but perhaps you are having trouble with the actual code-writing)
#2
10/16/2009 (7:42 pm)
Hi Ronny,

Thanks for the quick reply. Well, let´s say that I need to write and perform the for loop in C++ searching for objects variables contained in a SimSet and then do something with the results using torque script... is this request enough clear to get some code snippets?

What I need exactly is to know how to write the for loop in the C++ script and then how to call the c++ code from TS...

Thanks!
#3
10/16/2009 (8:29 pm)
Mike -
write it first in script and see if it's fast enough.
worry about optimization later.
#4
10/16/2009 (9:59 pm)
Orion -

Thanks. That´s why I´m asking this. I want to optimize a game that seems slower when performing for loops through TS.
#5
10/17/2009 (2:38 am)
Show the loop, the for loop might not be the problem.

Also have you tried timing the loop to see how long it is taking?
#6
10/17/2009 (11:42 am)
@Ben,

Thanks. Let´s say that the for loop is this:

for(%i = 0; %i < $GameObject.getCount(); %i++){
   %object = $GameObject.getObject(%i);
   %object.setUseMouseEvents(false);
   }

So, performing a search through 100 objects is being slow and I´m wondering if the search is possible in C++ while objects are still exposed to TS.

Mike
#7
10/17/2009 (12:12 pm)
Have you tried condensing the code to this and seeing if the omission of the %object improves things any? Admittedly, it may not be much, but for the iPhone, every little bit helps.
$GameObject.getObject(%i).setMouseEvents(false);
#8
10/17/2009 (2:57 pm)
@Ted,

Yes, but the problem is:

for(%i = 0; %i < $GameObject.getCount(); %i++){  
%object = $GameObject.getObject(%i);  
if(%object.isBeingUsed == true){//what if I need to use ifs???
%object.setUseMouseEvents(false);
}  
}


Thanks
#9
10/17/2009 (4:10 pm)
hey Mike -

the general approach for any sort of optimizing decision looks something like this:

1. make sure you know where the slowdown is. in your case, i would suggest commenting out the core of the loop, or skipping the loop altogether, and making as much of an apples-to-apples timing comparison as possible.

2. once you've identified the task which is the bottleneck, think of other ways to get the job done which avoid doing that task altogether, balanced, of course, against code complexity and programmer effort. in the example you've posted, i would spend some serious time here. that loop should execute quite fast when n = only 100 or so, so i assume that the loop is being called every frame or similar. think about ways to avoid calling it so often. eg, if you need to set useMouseEvents to false for all these objects on a regular basis, consider adding a new flag to the object via C along the lines of "myDoNotUseMouseEvents", and change the engine code to use "useMouseEvents && !myDoNotUseMouseEvents" everywhere it currently uses just "useMouseEvents". then just set that flag once and you're done.

3. if you decide you really have to do the task at hand, and the task is a bottleneck, then optimize it / convert it to C.

> I´m wondering if the search is possible in C++ while objects are still exposed to TS.

certainly. it might look something like this:
// not tested!
ConsoleMethod( SimSet, setChildrenUseMouseEvents, void , 3, 3, "(value)")  
{  
   bool value = dAtob(argv[2]);
   
   // "object" is the SimObject which this method is being called on. it's essentially "this".
   for (S32 n = object->size() - 1; n >= 0; n--)
   {
      GuiButtonBaseCtrl* child = dynamic_cast<GuiButtonBaseCtrl*>((*object)[n]);
      if (child != NULL)
      {
         // you'll need to change GuiButtonBaseCtrl::mUseMouseEvents from a protected to a public variable
         // for the following line to compile. or you could write a setter/getter. personally i'd just make it public.
         child->mUseMouseEvents = value;
      }
   }
}


#10
10/17/2009 (5:57 pm)
Quote:but the problem is

Well, that does necessarily change things :)
#11
10/17/2009 (6:27 pm)
@Orion,

Thanks for your kind explanation. I really appreciate when other people spent time to help others.

I will consider to try that code snippet, but right now I have discovered where the code is taking time:

for (%i=$searchEngine; %i<$NUM_WORDS; %i++)
   {
      if($words[%i] $= $searchedWord && $currentWordLenght >= $minimumLenghtAllowed)
      {
         echo("you have a valid word:" SPC $words[%i]);
         $aWordHasBeenMade = true;
         validWordIndicator.turnGreen();
         break;
       }
     }

The problem is that (it´s a word game) $NUM_WORDS may go from 4000 up to 10000 and that´s why the for loop is taking several time (one second)to perform when $num_words has a higher value and nothing when has a low value. I guess it doesn´t matter since the game is perfectly playable, but it will be great to improve this.

Thanks

Mike
#12
10/17/2009 (6:39 pm)
ah - yeah, if N is 4000 to 10000 stuff could get slow.
a few optimization suggestions for this particular code.

1. move the test on $currentWordLenght outside the loop.

2. even in torquescript, you could make this whole loop go away. do something like this:

// during game initialization, run this loop once:
for (%n = 0; %n < $NUM_WORDS; $n++)
{
%word = $words[%n];
$gKnownWords[%word] = true;
}

// then your test becomes simply:
%isValidWord = ($gKnownWords[$searchedWord]);

this is a little bit "ugly" because it accesses undefined variables, but i think torque just fails silently in that situation so you should be good.
#13
10/17/2009 (7:16 pm)
Yes, the best optimisation is to not need the lookup loop at all :)

Orion's solution is perfect, but I was about to suggest building an NSMutableDictionary and a lookup function exposed to TorqueScript :)
#14
10/17/2009 (10:12 pm)
Thanks Orion!

I will try this soon and I will let you know how it works.

Thanks to all.

Mike
#15
10/18/2009 (1:32 pm)
Though it would make the code look a little more bulky, you could always split your dictionary into separate, alphabetical Sim Sets (or a 2 dimensional simset if you know how). This way you can check for the first word in the string, use a switch statement to open up the relevant Sim Set, then search inside that Sim Set. Break this down further into the first 2 letters of the string (though the code would get even bulkier), you'd have even less of a loop for your processor to deal with.

P.S. Are you making a video game for your movie SiCKO, Mr. Moore? ;)