
FB II Compiler
PG PRO
Debugging
Memory
System
Mathematics
Resources
Disk I/O
Windows
Controls
Menus
Mouse
Keyboard
Text
Fonts
Drawing
Sound
Clipboard
Printing
Communication
ASM
|
TEXT
Quickly strip spaces from a string
I threw this function together, partly because I might need it but mostly for fun. Do you have any suggestions on how it can be improved?
----- Begin code example -----
'_____ Header ______________________________________
COMPILE 0, _CaseInsensitive _DimmedVarsOnly _NoRedimVars
WINDOW OFF
END GLOBALS
'_____ Functions ___________________________________
LOCAL MODE
'Length% = FN StripSpacesFromString (StringPtr&)
'
'Length% the new length of the string
'StringPtr& a pointer to a pascal string
'
'When called StripSpacesFromString strips all spaces from the beginning
'and end of a pascal string, just like the name implies. Not as fast as
'DEF TRUNCATE.
'
LOCAL FN StripSpacesFromString (StrPtr&)
` move.l ^StrPtr&,a0
` clr.l d0
` move.b (a0)+,d0
` beq ssend ;branch to end if length = 0
`ssloop1 ;remove spaces from end of string
` cmpi.b #$20,$FF(a0,d0.b)
` bne ssdone1
` sub.b #$01,d0
` beq ssend ;branch to end if length = 0
` bra ssloop1
`ssdone1
` move.l a0,a1
`ssloop2 ;count spaces at beginning of string
` cmpi.b #$20,(a1)
` bne ssdone2
` sub.b #$01,d0
` addq.l #$01,a1
` bra ssloop2
`ssdone2
` cmpa.l a0,a1
` beq ssend
` move.l a0,a2
` move.b d0,d1
`ssloop3 ;remove spaces from beginning of string
` move.b (a1)+,(a2)+
` sub.b #$01,d1
` bne ssloop3
`ssend
` move.b d0,-(a0)
END FN
LOCAL FN PrintExample (TheStr$)
DIM TheTime&, Count&, NewStr$
PRINT """ + TheStr$ + """;
TheTime& = FN TICKCOUNT
FOR Count& = 1 TO 25000
NewStr$ = TheStr$
FN StripSpacesFromString (@NewStr$)
NEXT
TheTime& = FN TICKCOUNT - TheTime&
PRINT TAB(28) """ + NewStr$ + """ TAB (55) TheTime& "ticks"
END FN
'_____ Main ________________________________________
DIM Count%, TheStr$
WINDOW 1
TEXT _monaco,9
CALL SETORIGIN (-3,-3)
PRINT "Before" TAB(28) "After" TAB(56) "Time to call 25000 times"
COLOR _zblue
FOR Count% = 0 TO 10
TheStr$ = SPACE$(Count%) + "FutureBASIC II" + SPACE$(10-Count%)
FN PrintExample (TheStr$)
NEXT
TheStr$ = SPACE$(24)
FN PrintExample (TheStr$)
TheStr$ = STRING$(24,&7A)
FN PrintExample (TheStr$)
PRINT CHR$(&0d) CHR$(&0d) CHR$(&0d)
COLOR _zblack
PRINT "(Press any key to continue)"
CALL SETORIGIN (0,0)
DO: UNTIL LEN(INKEY$)
Pontus Ilbring
There is one semi-mistake in your code. The line
cmpi.b #$20,$FF(a0,d0.b)
is not a valid 68K instruction, but is accepted by FB and assembled to
cmpi.b #$20,$FF(a0,d0.w)
The following version of your routine is shorter, uses fewer labels, and is possibly clearer. By use of dbXX instructions, all 3 loops have been reduced to minimum length. It is therefore a little faster, although I defy anyone to find a circumstance in which that could matter :-)
LOCAL FN StripSpacesFromString (StrPtr&)
' call like this: FN StripSpacesFromString (@anyString$)
_spaceChr=32
` movea.l ^StrPtr&,a0
` clr.w d0
` move.b (a0)+,d0
` beq.s ssend ; branch to end if length = 0
` subq.w #1,d0 ; adjust length for dbne
`ssloop1 ; count trailing spaces
` cmpi.b #spaceChr,(a0,d0.w)
` dbne d0,ssloop1
` beq.s ssend ; branch to end if length now = 0
` movea.l a0,a1
`ssloop2 ; count leading spaces
` cmpi.b #spaceChr,(a1)+
` dbne d0,ssloop2
` subq.l #1,a1
` cmpa.l a0,a1
` beq.s ssend ; branch if none
` movea.l a0,a2
` move.w d0,d1
`ssloop3 ; remove leading spaces
` move.b (a1)+,(a2)+
` dbra d1,ssloop3
`ssend
` addq.w #1,d0
` move.b d0,-(a0)
END FN
In fact, on my machine your timing loop:
TheTime& = FN TICKCOUNT
FOR Count& = 1 TO 50000
NewStr$ = TheStr$
FN StripSpacesFromString (@NewStr$)
NEXT
TheTime& = FN TICKCOUNT - TheTime&
is dominated by FB's slow copying of the string, and to show a real difference in speed between the two versions of FN StripSpacesFromString I had to copy the strings in assembler too. The moral is that your routine is plenty fast enough.
Robert Purves
|