last day (15 days later) » 

15:37
10
A: In MS BASIC, why is NEXT faster than NEXT I?

Leo B.The two statement forms are slightly different in meaning. The meaning of NEXT is, roughly, "increment the loop variable for the most nested loop and go to the next iteration of the loop". The meaning of NEXT I is, roughly, "while the mentioned variable is not the loop variable for the most ne...

Very interesting. What is the purpose of the second form though? Can you use it in an IF statement as a EXIT FOR proxy? Otherwise it seems like this would be an obvious source of hard to find errors!
@MauryMarkowitz It works like a combination of the C language's break for the inner loop and continue for the outer loop. I cannot think of a concrete example now, but I remember wishing for that in C a few times.
You'll exhaust the stack in a hurry, doing this, though. The J loop remains on the stack until satisfied.
In theory, I would say that any NEXT should always go to the last FOR. If there were a '50 NEXT J' that would be an error. One can leave off the I and J and avoid this problem, but then you lose code clarity. If you include them to clarify the code, you potentially introduce nasty runtime errors with simple typos. I wonder if the break/continue behaviour was really a feature, or just an unintended side-effect? If this is a feature, it's a very poor implementation (IMHO).
@JimMacKenzie: The "next I" will pop things from the stack until it finds an "i" one.
@MauryMarkowitz: The purpose of the construct is to allow loops or subroutine calls to be abandoned without accumulating on the stack. There may have been better ways of accomplishing that (I think AppleSoft included a POP statement, but was unique in that regard), but the approach used was workable. The performance difference here is minor, IMHO, compared to what could have been managed with some slight changes to the floating-point logic that would interpret a zero exponent byte as an indication that two remaining bytes held a 16-bit integer. I'm not sure exactly how much code...
...would have been needed to make all floating-point math recognize that construct, but on machines attached to a television, one could listen to the execution of for i=1 to 10000:next; each time i hit the next power of 2 would noticeably increase the time required for the floating-point addition.
15:37
@supercat - I believe your later part is about integer math, which is another mystery - do you know if using I% for the loop index had the same issue you mention?
@MauryMarkowitz: Use of integer variables would generally make things slower. I don't remember whether they were allowed as loop indices, but something like i%=i%+j% would be handled by converting both i% and j% to floating-point values, then performing the addition, and then converting the result back to an integer. If I were to hook up my VIC-20, it might be interesting to compare the time of a=0:b=1:for i=20000 to 29999:a=a+b:next with a=20000:b=20000:c=20001:for i=20000 to 29999:a=a+c-b:next. The latter might look like it should be slower...
...but it would require less left- and right-shifting because all computations and operands would either be within the range 16384 to 32767 or 32768 to 65535, and would thus never have to be shifted more than one bit left or right.
@supercat Depends on the implementation. The Elektronika Basic worked much faster with integer variables.
@MauryMarkowitz If memory serves, early implementations if BASIC did not have the NEXT form; the information about currently executing loops was kept in an array, and the NEXT var statement would find the increment, the bound and the location to jump to based on the variable name. At the last iteration the corresponding table entry would be discarded. The behavior we're discussing is the logical consequence of allowing NEXT while preserving backward compatibility.
@LeoB. - ah, very interesting! Actually, it was Atari BASIC's lack of such a stack that led me here, roundabout. In Atari BASIC, it iterated back through the lines to find the matching FOR, which was really slow.
Been using BASIC since 1980 and I learned something new today.
jdv
jdv
This feels a little like Duff's Device.
15:37
@MauryMarkowitz MS's implementation is a quirk. Attempting this in most non-MS BASICs results in an error
@scruss - BBC BASIC supports this also (ref). I know Sinclair BASIC didn't. Can't remember any others in enough detail, but it sounds more like a 50-50 hit rate to me...
as @Glen Yates already pointed out, it's all about variable handling in MS-BASIC (and here especially searching), not so much about the specific NEXT handling in MS-BASIC.
@LeoB. Nice explanation how the variations could be used, but not realyan anyser about the Speed difference, isn't it?
@Raffzahn The semantics of one form is a subset of the semantics of the other, therefore the first form is necessarily faster than the second.
@LeoB. Not nessecarry, as it's implementation dependant. If they had saved a pointer to the varible name instead of looking it up every time, the difference would be neglectable. Keep in mind, formal logic and real code does not always point the sameway.
@jdv Not really: there is no jump into the middle of the loop.

last day (15 days later) »