| 12-04-2002, 04:57 AM | #1 |
I have a nestled loop that has some weird behavior. I'm parsing a string of text as follows: for a = 1 to 16 for b = 1 to 200 check a substring (a_long_string[a], b, b+1) for a criteria if true then set flag = true endif next b next a It's not particularly important why I'm parsing the text, but when run as written above, the trigger never finishes. I have determined that the problem is almost certainly with the for loop, and not with the string or the programming itself. Using debugging, I can determine that the loop will consistantly run to a certain specific point, and then stop. Oddly, the more "junk" I put in the loop, the less of the loop is run (that is, the act of putting in dubugging code listing the variables actually further impairs the loops). When I lowered the inner loop to a 50-count loop, the whole loop worked as programmed. Given that the 16x50 loop worked as programmed, I tried to create 4 consecutive 16x50 loops for the same functionality. This didn't work, and conked out exactly where the above loop did. However, when I added a .1 second wait between the loops, the entire system worked as programmed. My suspicion is that when warcraft encounters a for loop, it gives the loop a certain amount of time (maybe a quarter of a second, say) to execute before it and the trigger containing it are automatically aborted. The timer on this seems to be reset by certain actions, including the "wait" function, but oddly, NOT including the endloop statement. Can anyone confirm, or even better, explain what's going on here? |
| 12-04-2002, 03:08 PM | #2 |
Funny you bring this up I was having problems with a loop last night. But I think it was tooo late and I was tooo tired to really fix it. Well Anyways you say parseing. I have two of them if you would like them it saves time :). One stored each word into an array and one returns a specific word. I will get these up tonight if you are interested. Thanks DKSlayer |
| 12-04-2002, 03:29 PM | #3 |
I have had the same experience. |
| 12-04-2002, 03:47 PM | #4 |
Guest | Try putting your .1 second wait within the outer loop (but after the inner loop) of your original setup. |
| 12-07-2002, 05:15 PM | #5 |
Just a quick update, if anyone cares: So to recap, if a long loop (say, a nestled 16 * 200 loop) takes too long to run, it looks like WC3 will abort the particular trigger the loop is in. This problem can not be solved merely by breaking the inner 200 loop into 4 50 loops. However, if there is a wait command between each of these 50 loops, the program will work. I mentioned a .1 second wait in a post above: for a = 1 to 16 for b = 1 to 50 do something next b wait .1 seconds for b = 51 to 100 do something next b wait .1 seconds etc next a However, this seemed to drastically increase runtime (surprise, surprise). I decided to reduce this to a ZERO second wait in hopes of speeding things up (that is the function was called, but with an input of 0). After I had done this, my run time was still over 30 seconds, and I concluded that the loop itself was just intrinsically slow. WRONG. Turns out that even a wait command of zero seconds takes a quite tangible ammount of time to run. When I upped the efficiency of my loop and shaved crucial seconds off of its run time, I decided to lessen the number of wait commands (so I went from a 4 * 50 inner loop to a 2 * 100 inner loop). My run time suddenly was cut in *half*. Getting more optimistic, I removed the wait functions entirely and watched my runtime sink below 5 seconds. This seems to be the lower limit (since indeed, it is a computationally intense loop), but luckily the loop now seems to take less time to run than WC3 cares about. The take home lesson for me, though, was that even a "wait 0 seconds" command takes at least .2 or so seconds to run, which is a LONG time compared with most other functions WC3 runs. One last question, though. Luckily, my original code was a bit bloated and inefficient, and with some thought, I could speed it up to the point where the runtime was below WC3's cutoff. What do we do when the loop is just intrisically long even when it's very efficient? Are there other commands besides "wait" that have the timer-reset effect that wait has? Any other command would be superior, since it would take less time to run. Perhaps a call DisplayTextToForce command would do the trick, just as well. Has anybody ever experimented with anything like this? |
| 12-07-2002, 05:32 PM | #6 |
I think it's only the wait command. A trigger only has a certain time to execute. If you do a big algorithm, you exceed it and the job is cancelled like you said. When wait is executed, all other triggers get a possibility to run. So you can do kinda multithreading. I think that a wait means to wait at least until this computing frame is finished. So a wait lets the real program continue in displaying the screen and stuff. |
