code optimization trick?
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
10-16-2007 10:06
/me adds http://jira.secondlife.com/browse/SVC-835 . From: someone SVC-835: Allow "Top Scripts on Parcel" for mainland land owners
Suggestion to allow mainland land owners the ability to find scripts that are misbehaving on their land and for script writers to be able to get performance measurements without needing to be an estate manager. Vote it up!
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
10-16-2007 10:09
From: Lear Cale Rule 1: optimize algorithms, not code, unless you know precisely WHY you're optimizing the code.
Totally agree. But there's also Rule 0: Don't optimize prematurely. It's easy to waste time optimizing things that don't matter. It's even easier to optimize code that will wind up getting changed or thrown away. From: someone However, in this particular case, I'll admit that Jessee has a good argument that knowing that "~x" means "x != 1" is a good thing to internalize and get used to, and then is not much of a readability block. So my argument for readability is relatively thin.
This is a plausible argument. I won't begrudge people who choose to use it, and if it becomes commonplace, and it might, then it will be an acceptable idiom. Sort of the way "for (;  " is idiomatic, in C, for "while (TRUE)", even though there ought be no difference in any modern C compiler. Of course, I'm biased by having used such compilers for a few decades myself. From: someone Nonetheless, I stand by Rule 1. That's the rule that makes us avoid open listens, and to consider how often each piece of code will run, and minimizing THAT rather than fussing to eliminate a single opcode here or there. That is the principle that, if taught to LSL coders, will have the biggest impact on overall script latency.
Again, I totally agree. I'll speculate that the single biggest improvement to the impact of scripts would be to get people to write llListen(0, "", llGetOwner(), ""  instead of llListen(0,"",NULL_KEY,""  accompanied by listen(...) { if (id == llGetOwner()) ... }. Even sample code, where you may not care about limiting listens to the owner, ought to use the former just in the way of setting a good example. This is also the point Qie was making, that using the library functions efficiently will have a far greater impact than most bit twiddling.
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
10-16-2007 10:19
From: Kidd Krasner I'll speculate that the single biggest improvement to the impact of scripts would be to get people to write llListen(0, "", llGetOwner(), ""  instead of llListen(0,"",NULL_KEY,""  accompanied by listen(...) { if (id == llGetOwner()) ... }. But that doesn't work for objects speaking to objects - the listen filter would punt anything not coming from the avatar that owns the object. A version of llListen that has an option for "filter out things not coming from my owner or objects my owner owns" would be really, really nice.
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-16-2007 13:28
From: Kidd Krasner I'll speculate that the single biggest improvement to the impact of scripts would be to get people to write llListen(0, "", llGetOwner(), ""  instead of llListen(0,"",NULL_KEY,""  accompanied by listen(...) { if (id == llGetOwner()) ... }. Even sample code, where you may not care about limiting listens to the owner, ought to use the former just in the way of setting a good example. My vote as to how to improve across the board would be to get everyone to understand how wastefull else if's are if done incorrectly. It is a really easy one for anyone to see. Get 21 else if's and check how much time it takes to get to the last else if. You will be looking at a couple of seconds. Then create a binary else if test. It takes no longer to get any one result as compared to any other: /54/02/144383/1.htmlMuch more simulator friendly. And even friendlier is to not do else if's in some cases: /54/05/207690/1.html
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
10-16-2007 13:31
From: Meade Paravane But that doesn't work for objects speaking to objects - the listen filter would punt anything not coming from the avatar that owns the object.
A version of llListen that has an option for "filter out things not coming from my owner or objects my owner owns" would be really, really nice. For objects talking to objects, use a nonzero (hopefully high, hopefully apparently random) channel number. That should be as good as listening to a single source.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
10-16-2007 13:47
From: Lear Cale As a senior software enginer for over 3 decades, currently working in a respected position in a highly respected and successful major network equipment vendor, I have found -- and the research shows -- that writing code for readability and maintainability counts far, far more than peephole optimization in the vast majority of cases.
Rule 1: optimize algorithms, not code, unless you know precisely WHY you're optimizing the code.
However, in this particular case, I'll admit that Jessee has a good argument that knowing that "~x" means "x != 1" is a good thing to internalize and get used to, and then is not much of a readability block. So my argument for readability is relatively thin.
Jessee also makes a good point that LSL scripts are an unusual case when assessing frequency -- that is, figuring out the rate at which a given piece of code is executed during normal use. For any given script it is normally quite low (with the notable exceptions of open listens), and it's the aggregation of lots of different scripts' event handlers that comprise the bulk of processing resources.
Nonetheless, I stand by Rule 1. That's the rule that makes us avoid open listens, and to consider how often each piece of code will run, and minimizing THAT rather than fussing to eliminate a single opcode here or there. That is the principle that, if taught to LSL coders, will have the biggest impact on overall script latency. I broadly agree, but with the caveat that code optimisations have a far greater significance when using LSL than in many other situations, simply because the required response times are often so short, and simple data manipulation functions often so peculiarly slow. Simple parsing that just uses multiple calls to string functions can take _seconds_. If there is an obscure "feature" which can speed up a process it may well behoove the scripter to use it, or something may become impossible. Having said that, I am an incredibly verbose scripter personally, and if I cannot find a way to do something in both a readable and effective way that does not involve odd hacks I will either find some other way to do it or remove it entirely. I have not yet encountered a situation where this does not work, and in my current paid projects, it is far more useful to have, say, a human-readable link-message API that happens to be a bit slower than some complex bitfield process, so that any other developer can pick it up and use it in a minimum of time regardless of their skill. (In another world, I have sacrificed _hours_ of runtime simply to maintain a development structure that is modular and maintainable, and do not regret it for a moment, but then, a few extra hours on days of processing is not that significant. Where microseconds are concerned, this is not the case.)
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-16-2007 14:34
From: Lear Cale For objects talking to objects, use a nonzero (hopefully high, hopefully apparently random) channel number. That should be as good as listening to a single source. And you should also specify the name of the object to be listening for, creating a really nice, tight listen.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
10-16-2007 15:00
Ordinal, my background includes automotive engine control, data acquisition, and computer networking, where latency issues are crucial -- far more so than with LSL in a reasonably healthy sim. No, the problem with LSL is that there are so many coders contributing code of differing quality. Furthermore, I don't believe that a handful of calls to string manipulation functions can take seconds in a sim that isn't experiencing heavy script lag to begin with. I would expect LSL functions that don't interact with the world (e.g., string manipulation) to operate on a efficiency level on par with Java or Python or other languages that are compiled to an interpreted byte code, with built-in functions implemented in languages like C and C++. These are much faster than what you're saying. If you have good evidence to the contrary, please let me know! Note that while the data printed in the thread mentioned above (  ) helps to illustrate the optimal way to do things, the times themselves are meaningless because they measure the llSay() calls more than anything else. Also, for lists with 8 items, the difference between a list of cascaded if-else requires, on average, 4 tests each time, whereas the binary if/else chain takes 3 tests. The difference in ease of maintainability of the simple cascading if-else is far greater (it's easy to goof up the binary tree when you add an entry). As the lists get longer, the savings grows, but the effort of maintaining an error-free, well-balanced tree grows as well. In the case of a cascaded if/else list with 8 items, the average time is about 4 msec. (Ditto for the binary if/else -- that is, the results are close enough that it's hard to measure the difference.) I find a call to llListFindList() for a list of 8 items is less than 8 msec, including the cost of the cast of the search string to a list. (Results were the same regardless of whether there was a match or not, and which item was matched -- however, my measurement method is +/- 50% or more; I'll be fixing that.)
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
10-16-2007 15:44
Well, one would _expect_ such things to be the case... as a singular example, I recently made a set of semaphore flags, the code for which I published. http://ordinalmalaprop.com/engine/2007/09/21/semaphore-unbound/ http://ordinalmalaprop.com/wiki/index.php?title=Script  emaphore Now, admittedly I do write these things so that people can easily follow them, but the function clean_msg, which really only runs through the original message character-by-character, can take seconds to complete (only one or two, but it really is so simple, in Perl it would take no time at all). In fact, that is the reason that it exists, to avoid unexpected delays during the actual signing of each character - better to have a slightly indeterminate function before each new message than possible multiple pauses during them. I'm sure that I could have optimised it, but this sort of function should be ignorable in terms of processing time when one has a relatively short message to deal with, below the thousands of characters, and it isn't in LSL. I have even considered sending processing off to an external script via llHTTPRequest for speed.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
10-16-2007 22:47
From: Ordinal Malaprop Now, admittedly I do write these things so that people can easily follow them, but the function clean_msg, which really only runs through the original message character-by-character, can take seconds to complete (only one or two, but it really is so simple, in Perl it would take no time at all). ...
I'm sure that I could have optimised it, but this sort of function should be ignorable in terms of processing time when one has a relatively short message to deal with, below the thousands of characters, and it isn't in LSL.
String handling in LSL is amazingly poor. I'd consider doing manual short-circuiting of the "...&& mode ==..." clauses, i.e. if (mode == 0) { if (llSubStringIndex(LETTERS, letter)... } else { if (llSubStringIndex(NUMBERS, lettter) .... } It's marginally more complex than your code, but worth it, I think. A cleverer approach would be to put the letters and numbers into a single string, so that you only have to do one search, and then make your tests based on the position. If you had string ALPHANUMERIC = "0123456789AB...Z" then you could test: idx = llSubStringIndex(ALPHANUMERIC... if (idx >= 10) ... else if (idx >= 0) .... I'm not bothered much by this, because the resulting code is still quite clean. But it needs to be commented properly. Also, isn't it worth switching to llStringTrim at the end of the function?
|
|
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
|
10-17-2007 05:55
From: Jesse Barnett And you should also specify the name of the object to be listening for, creating a really nice, tight listen. Now that I think about it, I kinda wonder about that, because I've really no idea how efficiently those filters are implemented. Assuming performance is the only consideration (not potential cross-talk), if a listen is on a unique channel, would it make it faster or slower to add object name to the filter conditions? or object key? and which of those would be faster? (Is there any possible way it could be faster with both name and key? I can't think of a filter implementation where the redundant condition could do anything but slow things down.) Meta-question: Are such things actually empirically knowable using the Estate tools? Even in an empty sim? I mean, as I understand it, this is getting at event dispatching that wouldn't be measured against any particular script... but maybe my mental model of event handling and script execution is just wrong.
|
|
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
|
10-17-2007 06:11
I'm of the opinion that this argument would go away if a little bit of love were invested in the LSL compiler. Even a few simple changes that don't break existing code would pay enormous dividends, such as a vaguely-efficient switch statement, lists where += is an O(1) operation, etc.
That way, we could keep more readable code without the resulting performance issues, and everybody wins. The problem is that everybody knows Mono is going to be used at some point down the line, so practically all development of LSL other than crashes and new functions has ceased in the meantime.
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
10-17-2007 08:16
From: Lear Cale For objects talking to objects, use a nonzero (hopefully high, hopefully apparently random) channel number. That should be as good as listening to a single source. This assumes that you're in range of only one set of these objects. If you want to make sure things work when there are multiple sets owned by different people, the listen event handler still has to check it's owner vs the owner of what is talking. I guess you could pick a semi-random channel to listen on by having both objects do some math on the owner UUID but, if everybody started doing that, you'd run into product crosstalk issues.. From: Stephen Zenith Even a few simple changes that don't break existing code would pay enormous dividends, such as a vaguely-efficient switch statement, lists where += is an O(1) operation, etc. /me nods, especially for switch/case! And a break statement to get out of loops. Yes, you can use goto but I'd still love to have break. edit: http://jira.secondlife.com/browse/VWR-1287 is a requset to add support for switch/case. Vote!!!
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
10-17-2007 13:13
From: Meade Paravane From: someone Originally Posted by Lear Cale For objects talking to objects, use a nonzero (hopefully high, hopefully apparently random) channel number. That should be as good as listening to a single source. From: someone This assumes that you're in range of only one set of these objects. If you want to make sure things work when there are multiple sets owned by different people, the listen event handler still has to check it's owner vs the owner of what is talking.
I guess you could pick a semi-random channel to listen on by having both objects do some math on the owner UUID but, if everybody started doing that, you'd run into product crosstalk issues.. Correct, and if you have to check owner, and if it's LIKELY that these objects will be in such proximity, and if the objects are very chatty, then you need to rethink. The bottom line for most performance issues in LSL scripts with simple logic is to count the frequency your handler gets invoked in the worst case situation -- counting ALL copies of your object in a reasonable but worst-case deployment. For example, the typical case of bad scripting: the open listen in a poseball, listens for anyone saying "show" or "hide" on channel zero -- BAD! Not only does the handler get called for every chat line in range, it's common to see scores of such poseballs placed together in groups where people can sit and chat. ARRRGH! So, say, one chat line per second, 25 poseballs = 25 handlers needlessly invoked per second. Big waste of CPU time. By itself, probably not a serious contributor to lag, but add other bad scripts elsewhere in the sim, and these things add up! Put them on channel 1, they no longer contribute to the sim's script-lag problems. It's also important to distinguish between necessary invocations and needless ones. Some objects have complex interactions and simply have to be a bit hoggy to do their jobs. I suspect that those aren't the major abusers, though -- in most cases. (AOs may be a counterexample -- the HAVE to do it, but damn, there are SO MANY of them!) Whenever you find yourself coding something that means "is this really for me", you should ask yourself -- how often might this happen, and is there a way to make it happen less often? Using a special chat channel is tool #1 in that kit, but certainly not the only one. If you find your handler only happens rarely, such as when your object is touched (and your object is not the floor, wall, or ceiling of a club), then most likely the handler isn't called often, and as long as you're not hogging the processor or doing fairly serious crunching, you should be good. BTW, the semaphore script mentioned above falls into an interesting category: simple compared to RL programs, but pretty intensive compared to the typical SL script. Cool idea, btw! However, count the number of string function calls in a given use: a half-dozen or more per character in the string to transmit. 100 character string? Say, 600 string function calls. At 2 msec per call, that's over a second right there, and I think it's more than that. I stand corrected that LSL should perform similarly to Java. Well, perhaps it SHOULD, but apparently it doesn't. One reason may be that Java can use lots of space, whereas LSL has to be very miserly of space. Still, the performance seems rather low -- more like what I used to expect from my trusty old PDP-8. Damn, that thing ran at ONE MEGAHERZ!
|
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
10-17-2007 13:33
From: Stephen Zenith I'm of the opinion that this argument would go away if a little bit of love were invested in the LSL compiler. Even a few simple changes that don't break existing code would pay enormous dividends, such as a vaguely-efficient switch statement, lists where += is an O(1) operation, etc. Yeah, no kidding! Note that O(1) for += would cost stack space, and it's a change to the VM and underlying data structure (list), not the compiler. An O(1) switch statement also requires a change to the underlying VM. However, with a switch statement and no VM changes, the compiler could at least construct a binary if/else tree, and as the number of cases grows past 8 the runtime savings would increase. Code readability increases in any event.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
10-17-2007 13:38
From: Kidd Krasner String handling in LSL is amazingly poor.
I'd consider doing manual short-circuiting of the "...&& mode ==..." clauses, i.e.
if (mode == 0) { if (llSubStringIndex(LETTERS, letter)... } else { if (llSubStringIndex(NUMBERS, lettter) .... }
It's marginally more complex than your code, but worth it, I think.
A cleverer approach would be to put the letters and numbers into a single string, so that you only have to do one search, and then make your tests based on the position. If you had string ALPHANUMERIC = "0123456789AB...Z" then you could test: idx = llSubStringIndex(ALPHANUMERIC... if (idx >= 10) ... else if (idx >= 0) .... I'm not bothered much by this, because the resulting code is still quite clean. But it needs to be commented properly.
Also, isn't it worth switching to llStringTrim at the end of the function? I shall certainly consider the suggestions, thank you, it could probably do with a bit of optimising as I wrote it in something of a hurry - but the point in quoting this is that, as you say, string handling in LSL is amazingly poor, and there does not seem to be any particular reason for that. The work I need to do to clean the input string, a regular expression in pretty much any other language could do in an utterly ignorable time. In that sort of situation, tiny hacks can make an awful lot of difference. I try not to use them on principle but sometimes they are the only thing between a working and not-working product. With Mono we may find this entirely disappears, and data-throwing-about time is reduced to microseconds. I would very much hope that this will be the case anyway.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
10-18-2007 02:55
From: Meade Paravane And a break statement to get out of loops. Yes, you can use goto but I'd still loke to have break.! ::recites after former programming logic instructer:: "properly constructed test do not need goto/break/jump statements" that said, It can be less intensive in scripting, and therefor useful,... it isn't always efficient to sub functions out and use return, and labels don't like multple jumps targeting them (as noted in wiki) for some unexplained reason... a bit frustrating
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
10-18-2007 08:15
From: Lear Cale The bottom line for most performance issues in LSL scripts with simple logic is to count the frequency your handler gets invoked in the worst case situation -- counting ALL copies of your object in a reasonable but worst-case deployment.
I'd say the bottom line is to look at both worst and typical case situations, as there could be tradeoffs. Although, since the worst case situation affects other users of the sim, common courtesy means giving it more weight than you might in other situations.
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
10-18-2007 08:26
From: Lear Cale An O(1) switch statement also requires a change to the underlying VM. However, with a switch statement and no VM changes, the compiler could at least construct a binary if/else tree, and as the number of cases grows past 8 the runtime savings would increase. Code readability increases in any event.
The ability to construct a binary tree depends upon how the syntax and semantics of the statement are defined. If the individual case values can be run-time expressions, then it's not possible when they're used. It would also be tricky if the C approach were used, i.e. each case falls through to the next unless there's a break, because then the order of cases becomes important. This doesn't mean it can't be done. Adding const to the language would help. But merely improving readability, without the optimization, would be worth it.
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
10-18-2007 08:32
From: Void Singer ::recites after former programming logic instructer:: "properly constructed test do not need goto/break/jump statements"
Beware of fanaticism in software religion. While I don't recall any justifications for goto/jump, the break statement is reasonable. In theory, any loop using a break statement could be recoded without it, but the theory doesn't say anything about whether the result is better or worse. Although I do believe that novice programmers will overuse the break statement.
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
10-18-2007 08:39
From: Void Singer ::recites after former programming logic instructer:: "properly constructed test do not need goto/break/jump statements" Sure. I don't _need_ them but that doesn't mean I can't _want_ them.. 
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
10-18-2007 08:46
From: someone properly constructed test do not need ... break ... statements Ivory tower bullshit. I'm a big advocate of structured use of continue, break, and return statements, based on lots of experience about what's maintainable. Use them to quickly eliminate the cases that are NOT under consideration, or errors, or simply handled special cases. Try to limit usage to one nest level deep. As a result, we end up with code whose logic is linear (mental complexity of N rather than the NlogN which you get with deeper nesting), and far easier to read and comprehend. As you read the function or loop, cases that are handled can be forgotten, focusing on what remains as you go lower. No need to constantly find out which "if" test a particular hanging error clause belongs to, scanning up and down in the source code. The biggest disadvantage with these "early returns" is that most optimizers aren't designed to handle them well, so they are less likely to find and optimize duplicate common code. (If you don't tend to write duplicate common code, this is less of an issue.) Gotos? I almost never use them. They're generally only advisable for very specific cases, and teachers are absolutely correct to teach to program without ever using them. Just like rules for good writing: learn to write (or code) well following the rules and get very good at it before ever considering when to break them. Then, when you break them, it's for a very specific and well-understood reason. It takes a very good programmer to know when to use gotos, and you'll become a good programmer fastest by not using them. If you're already a very good programmer, then you probably know what I'm talking about! 
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
10-18-2007 08:56
From: Kidd Krasner Beware of fanaticism in software religion. Except in things like consistancy of naming conventions. And in tabs vs spaces. Everybody knows literal tabs are better. From: Kidd Krasner While I don't recall any justifications for goto/jump, the break statement is reasonable. In theory, any loop using a break statement could be recoded without it, but the theory doesn't say anything about whether the result is better or worse. It's not _just_ loops.. Consider some of the listen event code we see posted around here. Being able to say.. // /me misses php tags :( do { if (optionA) { stuff; break; } ... 27 other options } while (FALSE)
...would be a win both in complexity and effeciency. While I'm in there, I'd like a "continue" statement, too. From: Kidd Krasner Although I do believe that novice programmers will overuse the break statement. The true novice will avoid them so their code won't break. Ha! Get it?? Never mind.. From: Lear Cale It takes a very good programmer to know when to use gotos, and you'll become a good programmer fastest by not using them. If you're already a very good programmer, then you probably know what I'm talking about!  In general, I think goto is evil but without things like switch/case, break and continue, they're sometimes the best bet.  (I have yet to use goto in an LSL script, BTW)
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
|
10-18-2007 09:46
I think we're in agreement, Meade. BTW, about the PHP tags: the simple workaround: hit the Quote button to see the code indented properly. OK, I bet you knew that! Oh: hard tabs in source files are EVIL. 
|
|
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
|
10-18-2007 11:23
From: Meade Paravane It's not _just_ loops.. ... do { ... break; ... ... 27 other options } while (FALSE)
Looks like a loop to me.
|