Fast For Loop - A collection from the community merged into a single really really fast loop.

Hey all,

Finally found a reason to get my web site up and running. This is the first post.

The Fast For Loop is the result of extensive testing with a collection of projects, examples, and ideas from members of the GameSalad community. I was originally in need of a loop when I came across what is called the Fisher-Yates shuffle, which is a highly efficient way of randomizing large data sets (especially in GameSalad). I originally completed my Fisher-Yates for GameSalad about 6 months ago using the timeStamp loop method. The result was more than acceptable for my use, thus completing my work with loops.

I recently revisited loops as my interest was re-sparked from the final pages of the Timers are for chumps thread. In the end, The Fast For Loop was spawned from that thread, with the majority of the credit belonging to members @tatiang for his "Study of Loops" project, @RThurman for the OldTime loop method, and @Socks for the idea of duplicating instructions.

Check it out here

Comments

  • SocksSocks London, UK.Member Posts: 12,822
    edited March 2013
    Wow! More excellent looping excellentness !

    Cheers for posting this ! How does this stack up against @domenius ' HyperLoops™ ? I suspect one system will be ideal for certain set ups while the other will be much more useful in others ?

    I think we need a LoopOff, the big players in the Loop business going head to head. FastForLoop™ vs HyperLoops™

    I just feel sorry for poor old GameSalad's timer, poor thing's been left for dead !

    : )
  • RThurmanRThurman Member, Sous Chef, PRO Posts: 2,879
    Holy Guacamole! That's fast!
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited March 2013
    No spawners? What kind of wizardry--- oh wait, I already used that phrase.

    Okay so here's what this reminds me of (remove the $ symbol):

    http$://www.youtube.com/watch?v=o-urnlaJpOA

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • ericzingelerericzingeler Member Posts: 334
    Wow! More excellent looping excellentness !

    Cheers for posting this ! How does this stack up against @domenius ' HyperLoops™ ? I suspect one system will be ideal for certain set ups while the other will be much more useful in others ?

    I think we need a LoopOff, the big players in the Loop business going head to head. FastForLoop™ vs HyperLoops™

    I just feel sorry for poor old GameSalad's timer, poor thing's been left for dead !

    : )
    Yea, I've been wondering about the applications for these. The HyperLoop in a way is self managed as nothing else will fire until it completes. The FastForLoop may require additional conditions, but overhead is very low and should play nice with other parts of your game simultaneously.

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    I just feel sorry for poor old GameSalad's timer, poor thing's been left for dead !
    Don't count it out just yet. It's still chuggin' along! 5000 iterations in 2.8*. Ha, beat that!


    *minutes. But it had time to go get coffee and read the newspaper. ;)

    Oh and don't tell anyone but that was the Preview timing... device timing was "unavailable at press time."

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • SocksSocks London, UK.Member Posts: 12,822
    *minutes.
    :)) :))

    Poor old 'timer' I actually feel sorry for it, someone should take it out into a field and shoot the poor thing, put it out of its misery.

    I hear they make glue from old behaviours.
  • SocksSocks London, UK.Member Posts: 12,822
    edited March 2013
    Yea, I've been wondering about the applications for these. The HyperLoop in a way is self managed as nothing else will fire until it completes. The FastForLoop may require additional conditions, but overhead is very low and should play nice with other parts of your game simultaneously.

    From what I can see they are both really quite brilliant ! Not so long ago these kinds of processes were a real challenge (for most of us anyway), now it looks like it might be trivial to shoot through a couple of thousand iterations without having to have the user wait around for a minute or so.
  • ericzingelerericzingeler Member Posts: 334
    Ok, my Fisher-Yates In-Place shuffle function using this loop has been posted. I had to drop the instruction set count to 6 to keep frame rate hovering around 50 on iPod 5th Gen. Runs like a champ!

    http://www.ezinterweb.com/2013/03/fisher-yates-in-place-shuffle-for_18.html
  • domeniusdomenius Member Posts: 108
    This is some interesting work here. I used a very similar method of looping when I was working on a pathfinding system. The only issue I find with this sort of looping in practice is that the code becomes difficult to maintain, but otherwise it is a sound method. Thanks for sharing!

    As a sidenote for those comparing this method of looping to HyperLoops, it is entirely possible that the fastest way to loop is to combine the two methods. If you duplicated your code within a HyperLoop as presented here and then tracked iterations using the same variables for both methods, you could take advantage of both systems. I think I'm going to toy with this idea today and post some results later. I always need faster ways to loop!
  • ericzingelerericzingeler Member Posts: 334
    @domenius

    Yep, you basically want to make sure your instruction set is complete before duplicating; but that being said, the beauty of this loop is that is plug and play. It'll run with 1 instruction set or 20. You can have 2 sets in part 1 and 8 sets in part 2. You never have to modify the loop structure itself or change any attributes, just copy and paste your instructions to change the speed.
  • JarrenHJarrenH Member Posts: 206
    I just want to say I've been tinkering around with this and I'm finding it to be incredibly useful! ( I'm still trying to figure out why it works though :p)

    One little issue I found, but I'm not sure if its related to the loop or my logic. Basicly I have it change some x and y values on each iteration, then spawn an actor at that location. Over in that actor, it checks its position, and will assign an image to itself dependent upon the position. This works great, until I try to add any behavior that takes time to happen. For example. I try to fade the actor in by interpolating from alpha 0 to alpha 1. The first two actors stay transparent, until the rest fill in, and then they jump to alpha 1. It's as if the first two have lagged behind.

    So I'm just wondering if this is a problem with the FastForLoop, or my logic. And if its my logic, feel free to gun me down for hijacking post and I'll start a new thread. ;)
  • CluvCluv Member Posts: 229
    edited April 2013
    I notice that in my project the loop gets hung up and freezes for a moment. Now, I am running a "Do/While" iteration inside of the loop where I am incrementing across a 19x19 table and updating all the values. Should I change my nesting?

    *Edit
    It seems I needed to change another timer which was causing the slowing.
  • ORBZORBZ Member Posts: 1,304
    edited May 2013
    I just stumbled onto this thread. Here is how I do fast iteration:

    Two ways:

    Option #1

    If I don't really care about the speed, and I just want clean code that's easy to debug - this works with Actions or Behaviors and is reasonably quick for small data sets.

    Timer - For 0s:
    - (your loop body inside the timer)

    Option #2

    Hyper Fast

    Slightly less clean, but still very simple, however only works with Actions - not Behaviors - this is probably a simplified version of what I see other people posting:

    Create a control variable, let's say "Iterate" as type Boolean

    Rule: Iterate = true
    - (your code here - remember, Actions only! No behaviors)
    - Change Attribute Iterate = False # Must always be last instruction inside the loop body.
    Otherwise:
    - Change Attribute Iterate = true

    The reason Actions only works is because Actions all happen inside the current animation frame, whereas Behaviors operate over time - therefor all actions can happen inside the single loop pass, but Behaviors will get cut off and not be able to finish.
  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    edited May 2013
    @ORBZ, this thread was the result of several of us trying to outdo each other with faster and faster loops. The every 0 seconds loop is great for some things (I use it often) but it's SLOW when compared to other methods. If you're trying to scan 1000 table rows, for example, it just gets silly to wait that long.

    Also, I can't get the Iterate loop to work. It just stays at counter=1. Can you post a demo?

    image

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • ericzingelerericzingeler Member Posts: 334
    Just updated the project file to v1.1 as I now have a better understanding of how behaviors run. The idea of the 2 loop parts in v1.0 didn't make sense.
  • ericzingelerericzingeler Member Posts: 334
    @tataing

    Ok, I've just seen the light. ORBZ example is missing one key element. A rule is required in the "otherwise" so the loop isn't initialized at scene start.

    Like so:

    image

    Here's a better version where you only need to manage 1 switch instead of 2. Just set the index to 0 < index < ceil to start/re-start the loop:

    image
  • ORBZORBZ Member Posts: 1,304
    Hmm... Maybe need to break it into two rules if not working correctly in otherwise block.

    Rule iterate = true
    - do stuff
    - iterate = false

    Rule iterate = false
    - iterate = true

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Hmm... Maybe need to break it into two rules if not working correctly in otherwise block.

    Rule iterate = true
    - do stuff
    - iterate = false

    Rule iterate = false
    - iterate = true

    That doesn't work. It's very similar to my favorite loop, an oldTime loop that just adds a time condition. It's available in this demo file: http://forums.gamesalad.com/discussion/comment/381275/#Comment_381275

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    @ericzingeler What are your initial values for self.index and self.indexSwitch? Are these reals?

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • ericzingelerericzingeler Member Posts: 334
    edited May 2013
    @ericzingeler What are your initial values for self.index and self.indexSwitch? Are these reals?
    Initial values are 0 for both. Both attributes are index type. To start loop, set index attribute to 0 < index < ceil

    Here's the project file:

    https://dl.dropboxusercontent.com/u/27937751/gs/modules/AutoMagicLoop_v1.0_2013_05_13.gameproj.zip

  • tatiangtatiang Member, Sous Chef, PRO, Senior Sous-Chef Posts: 11,949
    Thanks!

    New to GameSalad? (FAQs)   |   Tutorials   |   Templates   |   Greenleaf Games   |   Educator & Certified GameSalad User

  • ericzingelerericzingeler Member Posts: 334
    edited May 2013
    Note: My two examples I posted don't appear to be as fast as FastForLoop, almost twice as slow in fact... but, they're easy to implement and won't hinder frame rate.
  • CluvCluv Member Posts: 229
    @ericzingeler, you might be interested that I am using your FastForLoop for a project and CodeWizard is looking at the efficacy of the memory allocation/garbage collection for me. I am using your 1.0 version with only one "rule" in each iteration, but the results might be interesting. When he responds I would be happy to forward some of the info on to you guys on this thread.
  • ORBZORBZ Member Posts: 1,304
    edited May 2013
    @ericzingeler
    @tatiang

    I see that the example I gave doesn't work. That's strange, it used to work... ohwel.

    I looked over the examples you gave in your link. The problem with a lot of those "fast" examples is that they cheat. They don't really measure the speed of the loop, instead they do parallel work inside the loop body by incrementing the counter two or more times inside the loop body. That creates skewed results since you are no longer measuring the raw performance of a loop execution. So far I can't see anything faster and easier to maintain than an Every0 loop.

    Attached is a simple parallel processor that is super fast, way faster than the other examples I've seen, but not very practical. I'd stick with Every0 for everything but the most speed critical needs. It's just going to be much simpler to maintain your codebase. Furthermore it seems that CodeWizard is going to optimize timers at some point in the future so therefor Every0 should gain speed boost without you having to change your code to take advantage of it.

    Still, if your curious, here is a super fast way to do scalable parallelism to break the problem into smaller workers.

    Updated Parallel processor to be even faster... See post further down for attachment.
  • ORBZORBZ Member Posts: 1,304
    edited May 2013
    @ericzingeler
    @tatiang
    @RThurman

    Insanofast Parallel Processor v2 -- not really practical, but insane quick. ;)
  • ericzingelerericzingeler Member Posts: 334
    edited May 2013
    @ericzingeler, you might be interested that I am using your FastForLoop for a project and CodeWizard is looking at the efficacy of the memory allocation/garbage collection for me. I am using your 1.0 version with only one "rule" in each iteration, but the results might be interesting. When he responds I would be happy to forward some of the info on to you guys on this thread.
    Nice, looking forward to the results.

    @ORBZ

    Yep, that's fast. I think you've sealed the deal on making stuff happen as quickly as possible in GS. :)

    I've found that after using these very fast loops in real projects, no more than 2 rules per iteration is really required. A tenth of a second to shuffle 50 values in my table should be quick enough.

    The FastForLoop is good to grind out a chuck of stuff in 1 go; however, if you need a continuous efficient loop that wont bog down framerate, I'd go with the SimpleLoop or AutomagicLoop examples I posted earlier... they're not based on time.

  • CluvCluv Member Posts: 229
    @ericzingeler: I tried out the automagicloop using a mod>self.time%5 rule to reset the index and it won't run. It only runs on a click.... Thoughts?
  • ericzingelerericzingeler Member Posts: 334
    @Cluv

    Where are you placing this reset and when does it fire?
  • CluvCluv Member Posts: 229
    Sorry for the late response. I need to check. I decided to use the old structure in the mean time because I want to make sure my game logic works. When I can jump back over, I will let you know.

    But just an FYI, I am having great results using two FastForLoops in tandem on the newest nightly build. I am not noticing any slowing and the loops are moving pretty quick. I am running 180 iterations of two loops every 2 seconds, another 320 every 2 seconds, and 80 every 2-3 seconds. All in all I am using 11 loops currently to move stepwise through 3 tables (I am running an unsupervised neural network) and trying to stay behind garbage collection. Ultimately I will have to run 12-14 loops and these last 1-3 loops will be telling insofar as they will have to run the most dynamically of all my loops. Regardless, thanks for your work! It has allowed me to really take my project to a serious level.
Sign In or Register to comment.