Subject: Loop strangeness

From: [email-masked] (Jeff d'Arcy)
Date: Fri, 19 Feb 1993 11:38:26 -0800

I just ran the following two code segments on LambdaMOO, with interesting
results (arr is a 100-element array with each element equal to my .aliases):

	"Step through an array using a simple loop";
	for i in [1..100]
		for int in (arr)
			foo = int;
		endfor
	endfor

	"Step through an array using indices";
	for i in [1..100]
		for int in [1..length(arr)]
			foo = arr[int];
		endfor
	endfor

Either version takes about 20300 ticks.  The first version takes 0 seconds,
while the second takes 10; that's the part I didn't expect.  It seemed to me,
at first glance, that the implicit copy in the first version would be more
expensive than the array index in the second, but the opposite seems to be
true.

For those interested in writing efficient MOO code, this information may be
helpful.  I'd be interested in any explanations or comments from server
hackers, though.

	jeff

---

From: Roger Crew <[email-masked]>
Date: Fri, 19 Feb 1993 12:39:54 -0800

>   I just ran the following two code segments on LambdaMOO, with
>   interesting results (arr is a 100-element array with each element
>   equal to my .aliases):
>   

I'm slightly mystified since the second version should be taking
twice as many ticks (foo = int is 1 tick, whereas foo = arr[int] 
should be 2 ticks).

Before Pavel implemented reference counting the first version was 
*much* faster, since the first loop only copied each element of arr
into int once whereas the second loop was copying all of arr for
each index operation.  Even with reference counting in place, I 
expect that you still have a certain amount of interpretive overhead
for each index operation (and with the length() function for that 
matter).  I'm not sure whether this accounts for all of the difference, 
though...

--
Roger Crew
Internet:   [email-masked]
LambdaMOO:  Rog

---

From: Pavel Curtis <[email-masked]>
Date: Fri, 19 Feb 1993 16:37:17 -0800

> Date:	Fri, 19 Feb 1993 11:38:26 -0800
> From:	[email-masked] (Jeff d'Arcy)
> 

I was unable to reproduce your results on LambdaMOO just now.  I first created
a property on myself containing 100 copies of your player's alias list, which
is a list of two short strings.  I then added the line

	arr = player.arr;

to the front of each of the above code pieces and typed them as `;' (eval)
commands.  The second one ran out of ticks, so I reran both programs using 90
as the limit in the `for i' loop instead of 100.  Both tests succeeded then, so
I ran each one six times.  For the first one, I got these numbers of seconds:

	0, 0, 0, 0, 0, 1

and 18183 ticks.  For the second one, I got these numbers of seconds:

	1, 0, 0, 0, 0, 1

and 27363 ticks.

The difference in ticks is due to the 90 calls to `length(arr)' and the
90 * 100 uses of indexing in `arr[int]':

	90 * 2 + 90 * 100 * 1 = 9180 = 27363 - 18183

The slight difference in running times is also attributable to the extra
operations performed by the second program.

There is no copy performed of any list or sublist in executing this piece of
code, since the server now uses reference-counting instead of copying wherever
it can.

Conclusion: it does not appear that there is an appreciable CPU time benefit to
writing in one style or the other, but a possibly significant ticks benefit
accrues to code written in the first style.

	Pavel