In response to Android Data
I personally wouldn't use it just to remove redundancy. I'd use (in DM) either other procs, or live with it. Combining it, like:

if( ckey == "androiddata" || ckey in allowed ) src << X.password


Since such optimizations can be made, I'll say no myself.
In response to Krispy Kreme
Krispy Kreme said:
Since such optimizations can be made, I'll say no myself.

What are you talking about. =|
In response to Elation
It's not as much optimization as it is...meh. Refactoring, I guess I could say. The reason he needed goto was because his design was flawed to begin with.
In response to Android Data
Shouldn't that be X.allowed anyway?
And no, like Krispy Kreme said, you can just combine the ifs.
In response to Android Data
Android Data wrote:
I'm curious. Would the code below (which I just created but use a similar version of in other code) be considered a good way of using goto?

No; And as mentioned, if you have to ask yourself, it isn't.

> pword
> var
> name="secret area" //label
> password="secret" //password
> list/allowed=list("androidlore") //keys allowed to see the password
>
> mob/verb/pwords()
> var/list/pwords[0]
> pwords+=new/pword
>
> for(var/pword/X in pwords)
> if(ckey=="androiddata")goto allowed
> if((ckey in allowed))goto allowed
> return
> allowed:
> src<<X.password
>


Non-goto version, far cleaner and simpler:
mob/verb/pwords()
var/list/pwords
pwords = new()
pwords+=new/pword
for(var/pword/X in pwords)
if(ckey=="androiddata" || ckey in allowed)
src << X.password
In response to Alathon
Alathon wrote:
Android Data wrote:
I'm curious. Would the code below (which I just created but use a similar version of in other code) be considered a good way of using goto?

No; And as mentioned, if you have to ask yourself, it isn't.

         if(ckey=="androiddata"||(ckey in allowed))


Small fix. I misinterpreted it.
I ment something like this:

pword
var
name="secret area" //label
password="secret" //password
list/allowed=list("androidlore") //keys allowed to see the password
user
var
ckey="androidlore" //ckey of user
view_pword=1 //if the user is allowed to view passwords

mob/verb/pwords()
//<global>
var/list/pwords[0]
pwords+=new/pword
var/list/users[0]
users+=new/user
//</global>

for(var/pword/X in pwords)
if(ckey=="androiddata")goto allowed
else for(var/user/X in users)if(X.ckey==ckey&&view_pword)goto allowed
return
allowed:
src<<X.password
In response to Android Data
Same deal. These sorts of situations, no matter the minor detail here, really aren't suited for goto and you don't even need a nested loop here.

pword/var
password=""
tag=""
list/viewers=list()

mob/var/view_pword = 0 // View passwords?

mob/verb/pwords()
var/list/pwords = new()
pwords += new/pword()
for(var/pword/P in pwords)
if((ckey=="androiddata" || ckey in P.viewers) && view_pword)
src << P.password
In response to Alathon
Hmm. Okay, I've learnt some more. Thanks!
In response to Airjoe
I kind of wonder about these results, whether extended trials would give you different results (as they well might). I don't mean longer loops, but rather just doing the three routines in sequence again and again--or maybe even randomizing their order. Of course, you also have to fix your loops because in One() and Two() you're really only showing the numbers 2 through 5000, whereas in Three() you show 1 through 5000.

If goto is taking longer, I suspect a syntax error in your code may be to blame. You have a colon in the goto statement that is not needed.

I'm not sure how the loops are implemented internally, but I'd be very surprised if it doesn't boil down to a goto instruction just as when C compiles to assembly. That being the case, your version with goto should always be faster because it's marginally more efficient. The assumption doesn't apply quite as well to interpreted languages as to machine code, but still it has some validity.

If DM compiles anything like C, a for() loop is implemented like this:
var/i=1
while(i<5000)
++i
world << i

...which translates to:
var/i=1
condition:
if(i>=5000) goto afterloop
world << i
endloop: // target for continue statement
++i
goto condition
afterloop:

In C, at least in older compilers (newer ones may use this optimization), you can eliminate one of the goto statements each time around by "flipping" the loop. A flipped loop is a do-while instead of a while. In C you'd implement it (somewhat hackily) like so:
var/i
if(i<5000)
do
++i
world<<i
while(i<5000)

In a goto format, it looks like this:
var/i
goto condition
beginloop:
++i
world << i
condition:
if(i<5000) goto beginloop

In machine code, this is a huge advantage because all modern processors use prefetching. They grab instructions by looking ahead to where the instruction pointer will be pointing next, thereby reducing the number of slower memory access operations. Prefetching only works if it knows where to look, so for absolute jumps it always knows where to fetch the next instructions. For conditional jumps, it has to guess based on how the loop is likely to go; if it guesses wrong, it has to throw out the instructions and fetch new ones.

The upshot is that an unflipped loop has two gotos every loop; a flipped loop has just one. Even in interpreted code, a flipped loop should be marginally faster based on its simplicity.

Lummox JR
Page: 1 2