Author |
Topic: Easily add stuff (Read 3453 times) |
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Easily add stuff
« Reply #15 on: Oct 13th, 2013, 11:30am » |
|
on Oct 13th, 2013, 10:30am, Matt wrote:| OK. Slightly edited version of DLG_LIB.bbc |
|
Just a quick query. There are one or two places where you have used a WHILE..ENDWHILE loop when, superficially, a REPEAT..UNTIL or FOR..NEXT loop appears to be more appropriate. WHILE loops are slower than either of the other kinds (because they involve searching through the code at run-time, which is inefficient) so they are best avoided if that is easily achieved.
It's no coincidence that the original BBC BASIC (on the BBC Micro) had FOR..NEXT and REPEAT..UNTIL but not WHILE..ENDWHILE!
Richard.
|
|
Logged
|
|
|
|
Matt
Developer
member is offline


Gender: 
Posts: 210
|
 |
Re: Easily add stuff
« Reply #16 on: Oct 13th, 2013, 3:25pm » |
|
on Oct 13th, 2013, 11:30am, Richard Russell wrote:| There are one or two places where you have used a WHILE..ENDWHILE loop when, superficially, a REPEAT..UNTIL or FOR..NEXT loop appears to be more appropriate. |
| You're probably right. I think the reason I chose WHILE..ENDWHILE is the avoidance of a conditional line to check to see if the second value was 'less than' the first. However, in a procedure that might well require a significant number of loops to complete, a conditional line may well be advised.
Matt
|
|
Logged
|
|
|
|
Matt
Developer
member is offline


Gender: 
Posts: 210
|
 |
Re: Easily add stuff
« Reply #17 on: Oct 13th, 2013, 3:52pm » |
|
on Oct 13th, 2013, 11:30am, Richard Russell wrote:| WHILE loops are slower than either of the other kinds (because they involve searching through the code at run-time, which is inefficient). |
| Out of pure curiosity, I tried some rudimentay experiments and seemed to find that the REPEAT..UNTIL loop had a similar (if not slightly longer) loop time to that of WHILE. Does REPEAT not have to search as well? From previous posts I'm aware that FOR does not recheck a TO <numeric> unlike UNTIL <t-cond> or WHILE <t-cond>? Am I getting somewhere, or am I off the track? This seems to be basic stuff that I should already know, but obviously I don't. 
Matt
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Easily add stuff
« Reply #18 on: Oct 13th, 2013, 4:20pm » |
|
on Oct 13th, 2013, 3:52pm, Matt wrote:| Out of pure curiosity, I tried some rudimentay experiments and seemed to find that the REPEAT..UNTIL loop had a similar (if not slightly longer) loop time to that of WHILE. |
|
What was the initial condition? The case when a WHILE loop is slow is, of course, when the initial condition is FALSE because it's then that the search to find the ENDWHILE has to take place (and because it must allow for things like nested WHILE loops this is quite complex).
Here is a test of the relative slowness of WHILE:
Code: S% = TIME
FOR I% = 1 TO 10000000
WHILE FALSE
A = PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI
A += PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI
A += PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI
ENDWHILE
NEXT
F% = TIME
PRINT "Time for WHILE was "; F%-S% " centiseconds"
S% = TIME
FOR I% = 1 TO 10000000
IF FALSE THEN
REPEAT
A = PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI
A += PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI
A += PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI+PI
UNTIL TRUE
ENDIF
NEXT
F% = TIME
PRINT "Time for IF/THEN plus REPEAT was "; F%-S% " centiseconds" On my PC the WHILE version took more than four times as long as the IF/THEN/REPEAT version.
Quote:| Does REPEAT not have to search as well? |
|
No. A REPEAT loop is always executed at least once. Neither of the loop types supported in the original 6502 versions of BBC BASIC involves any kind of searching.
WHILE is unique in BBC BASIC in having to do a 'linear' search through what could be a considerable amount of code. No other statements ever need to search through more than one line of code. Of course if you know for sure that the initial condition will always be true then the search doesn't need to take place and WHILE isn't slow, but in that case a REPEAT loop is likely to be more appropriate anyway!
Richard.
|
|
Logged
|
|
|
|
Matt
Developer
member is offline


Gender: 
Posts: 210
|
 |
Re: Easily add stuff
« Reply #19 on: Oct 14th, 2013, 04:53am » |
|
on Oct 13th, 2013, 4:20pm, Richard Russell wrote:| What was the initial condition? The case when a WHILE loop is slow is, of course, when the initial condition is FALSE because it's then that the search to find the ENDWHILE has to take place (and because it must allow for things like nested WHILE loops this is quite complex). |
|
Yes. The only condition that was FALSE was the last one, so any time lag would be on that final one. Overall a realatively small drop.
Quote:| WHILE is unique in BBC BASIC in having to do a 'linear' search through what could be a considerable amount of code. No other statements ever need to search through more than one line of code. |
|
I understand the need for the WHILE to search through the code until it finds the matching ENDWHILE, but doesn't the IF have to search through until it finds the matching ENDIF? Or is there something different about the way it searches?
Matt
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Easily add stuff
« Reply #20 on: Oct 14th, 2013, 08:43am » |
|
on Oct 14th, 2013, 04:53am, Matt wrote:| Yes. The only condition that was FALSE was the last one, so any time lag would be on that final one. |
|
"The only condition that was FALSE was the last one". That's stating the obvious - it's inherent in how WHILE..ENDWHILE loops work (they loop while the condition is true and terminate as soon as the condition is FALSE)!
And anyway even on that final FALSE condition no searching is required. If the initial condition is true, WHILE..ENDWHILE basically runs at the same speed as REPEAT..UNTIL.
Quote:| doesn't the IF have to search through until it finds the matching ENDIF? Or is there something different about the way it searches? |
|
A single-line IF does have to search through code, and some of the same issues apply as for WHILE (although not nesting), but the important factor is that the maximum amount of code it has to search through is one line (i.e. about 250 bytes).
A multi-line IF..ENDIF doesn't have to search through any code as such, so it's much faster than WHILE..ENDWHILE. WHILE has to cope with the possibility that the token for ENDWHILE might be found within a text string, or a REMark, or a DATA statement, or after a line-continuation character. And a line-continuation character itself can be found in an encoded line number! So (in addition to needing to deal with nested WHILE loops) the search is complicated and messy.
It's in the knowledge of how horrible the code is that I like to avoid WHILE whenever I can (plus of course having spent 20-odd years programming in versions of BBC BASIC which didn't have WHILE at all)! I can understand why Acorn added WHILE, because it's a standard feature of other languages, but as I said it's uniquely messy in an interpreted language.
One reason why Brandy is so much faster than any other version of BBC BASIC is that it doesn't do any of this crazy stuff. It determines the position of the terminating ENDWHILE 'in advance' so no searching at run-time is required at all! You might argue that this is a vastly superior method to what Acorn's and my versions of BBC BASIC do, but I wouldn't care to comment. 
Richard.
|
| « Last Edit: Oct 14th, 2013, 09:05am by admin » |
Logged
|
|
|
|
|