home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
database
/
db3tips2.zip
/
DCRUNCH.TXT
< prev
next >
Wrap
Text File
|
1986-07-01
|
11KB
|
323 lines
dCRUNCH for Program Speed
(PC Magazine Vol 5 No 13 Power User)
In both "Pseudo Compiler for dBASE II" (PC Mag Vol 5 No 5 Power
User) and "dBASE Speed Tips" (PC Mag Vol 5 No 1 Power User), the point
is made that dBASE programs will execute faster if leading and trailing
spaces, blank lines, and "*" lines are stripped out and if everything
(except quoted text) is capitalized. (See the file DB3MISC.TXT for
the articles cited here.)
To facilitate the necessary file preparation, dCRUNCH.BAT and
dSTRIP.COM will convert a 64K command file in under 6 seconds. Before
running programs through the DOS filter, edit out any single apostrophes
inside NOTE or TEXT/ENDTEXT statements, since capitalization is based
on pairs of apostrophes, double quote, or brackets. Note also that
everything inside a TEXT/ENDTEXT statement will be capitalized and
left-justified unless you first enclose it in quotes, then edit out
the quotes later.
The syntax for the command is:
DCRUNCH [d:][path][filename]
and you should omit the .PRG filename extension.
dBASE's interpreter is its weakest (slowest) link. When a command
is issued, the interpreter 1) parses the full command line; 2) discards
leading spaces; 3) indexes to the first space to identify the verb;
4) truncates the string if it's longer than four characters; 5) converts
it to uppercase; 6) searches its lookup table of initial verbs; and,
7) gets down to business. If you write a long NOTE or "*" comment, the
interpreter looks at every byte, savors a delicate sample, then spits
it out. The same applies when you add a comment after ENDIF or ENDDO,
or when you indent command lines for legibility.
Take, for example, this simple iterative loop:
variable_x=0
DO WHILE variable_x<1000
variable_x=variable_x+1
*This is a long comment line
*explaining what's going on
ENDDO
dCRUNCH shortens processing of this loop over 25 percent -- from
58 to 42 seconds. The biggest offender is the"*" line -- 13 seconds;
a long comment tacked on to the ENDDO will have the same effect.
Shortening "variable_x" to "x" shaves another 6 seconds.
There is no measurable difference is one blank line is added, but
a large overhead begins to accumulate with each additional blank line.
Five blank lines increase execution time of 1,000 loops by 11 seconds.
dCRUNCH's side effects are substantial. A program that is all-
capitalized and left-justified without comments or mnemonic variable
names is awful to read and a nightmare to modify 6 months later. And,
in most applications, a few extra milliseconds inside a loop is the
least of your problems. But if you need maximum speed inside an
intensive loop -- like passing each record in a file -- dCRUNCH is
just the ticket.
- - - - -
dCRUNCH.BAT:
ECHO OFF
REM dCRUNCH.BAT Speeds dBASE routines. Calls dSTRIP.COM
IF %1/==/ GOTO noparm
IF NOT EXIST dstrip.com GOTO nocom
IF EXIST %1.prg GOTO strip
ECHO -----
ECHO File %1.PRG not found
IF EXIST %1 ECHO Please specify the file without .PRG extension
GOTO noparm
:strip
IF NOT EXIST %1.prk GOTO work
ECHO -----
ECHO A back-up file %1.PRK already exists and will be overwritten.
ECHO Hit CTRL-BREAK followed by Y to interrupt or ...
PAUSE
DEL %1.prg
:work
ECHO Streamlining %1.prg. Original version is saved as %1.prk
REN %1.prg %1.prk
dstrip <%1.prk >%1.prg
GOTO end
:noparm
ECHO SYNTAX: DCRUNCH [d:][path][filename] (omit ".prg" extension)
GOTO end
:nocom
ECHO File DSTRIP.COM not found.
:end
- - - - -
DSTRIP.ASM (to create DSTRIP.COM):
; DSTRIP - DOS filter to remove leading and trailing blanks, blank
; lines and comment lines from dBASE command files, and to
; capitalize text not in quotation marks.
;
comseg segment para public 'code'
assume cs:comseg,ds:comseg,es:comseg,ss:comseg
org 100h
start proc far
cld
mov bl,00000001b ;the bits in the BL register will hold
;the following information when set to 1:
;0-bit only tabs and blanks encountered
; in current line
;1-bit a '*' encountered as first
; character of line
;4-bit char inside 'single' quotes
;5-bit char inside "double" quotes
;6-bit last char was linefeed
;7-bit last char in *-line was a ';'
xor dx,dx ;DX will count blanks/tabs after a char
load: push bx ;save registers and
push dx
mov dx,offset data ;read into memory
mov cx,64000 ;64K bytes
xor bx,bx ;from standard input
mov ah,3fh ;with DOS function call
int 21h
pop dx ;restore registers
pop bx
or ax,ax ;AX has number of bytes read; test for 0
jnz load0
jmp done
load0: mov cx,ax ;move count into CX
mov si,offset data ;and position index registers for
mov di,offset data ;a string move
scan0: lodsb ;fetch a byte into AL
cmp al,26 ;end of file?
jz store ;if so, store and get out
test bl,01000000b ;LF on previous fetch?
jz next ;if not, skip
or bl,1 ;set beginning of line bit
and bl,10111111b ;and reset the LF bit
test bl,10000000b ;a ';' at end of line?
jnz next0 ;if yes, skip
and bl,11111101b ;otherwise reset '*'-bit
next0: and bl,01111111b ;reset ';'-bit
next: cmp al,59 ;a ';'?
jnz next1 ;if not, skip
or bl,10000000b ;set ';'-bit
jmp short next5 ;and do loop routine
next1: cmp al,32 ;blank?
jz count ;if yes, check whether to count it
cmp al,09 ;tab?
jnz next2 ;if not, skip count
count: test bl,11b ;are we at beginning of line or in a '*'-line?
jnz loop ;if yes, loop and omit
inc dx ;otherwise count the blank/tab
jmp short store ;and store it
next2: cmp al,13 ;CR?
jz out ;if yes go to end of line routine
next3: cmp al,10 ;LF?
jnz next4 ;if not, go on checking
or bl,01000000b ;set end of line bit
jmp short out ;and go to end of line routine
next4: test bl,1 ;have we seen any nonblank/tab char before?
jz next6 ;if yes, ignore the next step
cmp al,42 ;a '*'?
jnz next5 ;if not, skip
or bl,10b ;otherwise set the '*'-bit
next5: and bl,11111110b ;and in either case we have nonblank/tab char
next6: xor dx,dx ;set blank/tab count to 0
out: test bl,11b ;are we at beginning of line or in a '*'-line?
jnz loop ;if so, ignore (includes CR/LF of blank lines)
sub di,dx ;DX is non-zero only if we encountered a CR
xor dx,dx ;reset DX to 0
and bl,01111111b ;reset ';'-bit
caps0: jmp short caps ;capitalize
store: stosb ;store char
loop: cmp al,26 ;test for end of file
loopnz scan0 ;and loop for next fetch
push ax ;save registers
push bx
push dx
mov dx,offset data ;compute the numbers of bytes stored
mov cx,di
sub cx,dx ;in CX, and
mov bx,01 ;write to standard output
mov ah,40h ;with DOS function call
int 21h
pop dx
pop bx
pop ax
cmp al,26 ;end of file?
jz done
jmp load ;if not, read another 64K bytes
done: int 20h ;end program
caps: cmp al,39 ;single quote?
jnz quot ;if not, check double quote
test bl,100000b ;is double quote bit set?
jnz store ;if yes, ignore
xor bl,010000b ;(re-)set single quote bit
jmp short store
quot: cmp al,34 ;double quote?
jnz caps01 ;if not, skip
xor bl,00100000b ;(re-)set double-quote bit
jmp short store
caps01: test bl,00110000b ;any quote-bits set?
jnz store ;if so, don't capitalize
caps1: cmp al,97 ;below 'a'?
jb store ;if so, leave it alone
caps2: cmp al,122 ;above 'z'?
ja store ;if so, don't change
caps3: and al,5fh ;otherwise capitalize
out2: jmp short store
start endp
data:
comseg ends
end start
- - - - -
You can use DEBUG to create DSTRIP.COM by issuing the command:
DEBUG < DSTRIP.INP
with the following. DEBUG will use DSTRIP.INP as its input to create
the .COM file.
N DSTRIP.COM
A
CLD
MOV BL,01
XOR DX,DX
PUSH BX
PUSH DX
MOV DX,01CE
MOV CX,FA00
XOR BX,BX
MOV AH,3F
INT 21
POP DX
POP BX
OR AX,AX
JNZ 011C
JMP 01A4
MOV CX,AX
MOV SI,01CE
MOV DI,01CE
LODSB
CMP AL,1A
JZ 0184
TEST BL,40
JZ 013F
OR BL,01
AND BL,BF
TEST BL,80
JNZ 013C
AND BL,FD
AND BL,7F
CMP AL,3B
JNZ 0148
OR BL,80
JMP 0171
CMP AL,20
JZ 0150
CMP AL,09
JNZ 0158
TEST BL,03
JNZ 0185
INC DX
JMP 0184
CMP AL,0D
JZ 0176
CMP AL,0A
JNZ 0165
OR BL,40
JMP 0176
TEST BL,01
JZ 0174
CMP AL,2A
JNZ 0171
OR BL,02
AND BL,FE
XOR DX,DX
TEST BL,03
JNZ 0185
SUB DI,DX
XOR DX,DX
AND BL,7F
JMP 01A6
STOSB
CMP AL,1A
LOOPNZ 0124
PUSH AX
PUSH BX
PUSH DX
MOV DX,01CE
MOV CX,DI
SUB CX,DX
MOV BX,0001
MOV AH,40
INT 21
POP DX
POP BX
POP AX
CMP AL,1A
JZ 01A4
JMP 0105
INT 20
CMP AL,27
JNZ 01B4
TEST BL,20
JNZ 0184
XOR BL,10
JMP 0184
CMP AL,22
JNZ 01BD
XOR BL,20
JMP 0184
TEST BL,30
JNZ 0184
CMP AL,61
JB 0184
CMP AL,7A
JA 0184
AND AL,5F
JMP 0184
RCX
0CE
W
Q