I finally got around to doing a little experiment.
Last Christmas, Matthew Chappee posted some code on the PowerBASIC
BBS, a C program that calculated pi to about 1000 digits. It seems
he'd been taking the usual verbal abuse from some co-workers, who
were C programmers. You all know the song and dance.
This pi program was the C programmers' answer to Matthew's challenge
to show him a program they thought was far beyond the powers of
BASIC. The code is very terse and no doubt they thought to confuse
him with obfuscated C.
A couple of weeks later, Ray Crumrine posted a direct translation
into PowerBASIC, along with the warning that it ran "...as slow as
mollases." I saved both versions and put them aside.
Today I got around to compiling the C version under Turbo C 2.0,
then using Turbo Profiler 1.0 to compare the C version to the
PowerBASIC version. Surprise! The PB3 version (with no inline
assembler) ran faster than the C version, by about 15%.
Here is the code for each...
/* The C version */
#include
#define A 10000
#define MAX 14000 // Multiple of 14 -- Number of digits = MAX*4/14
// MAX=number of digits*14/4
unsigned long a,b,c,d,e,f[MAX+1];
void main()
{
while(a!=MAX+1)
f[a++]=2000;
for(b=MAX;b;b-=14)
{
e=b*2-1;
for(a=b-1;a;a--)
{
c=((c/e)*a)+f[a]*A;
e-=2;
f[a]=c%e;
}
printf("%.4d",d+c/A);
d=c%A;
}
puts("\n");
}
'The PowerBASIC version:
$OPTIMIZE SPEED
$CPU 80386
$LIB ALL OFF
$OPTION CNTLBREAK OFF
%g = 10000 'Same as #define A 10000
%maximum = 14000 'Same as #define MAX 14000
a??? = 0 'Same as unsigned long a,b,c,d,e,f[MAX+1]
b??? = 0 'Could have used DIM a AS DWORD, DIM b AS DWORD, etc.
c??? = 0
d??? = 0
e??? = 0
DIM f(%maximum + 1) AS DWORD
u$ = "####" 'Do this once for speed
CtrlBrk$ = CHR$(0,0) 'ditto for this
DO WHILE a??? < (%maximum + 1)
f(a???) = 2000
a??? = (a??? + 1) 'increment a???
LOOP
b??? = %maximum 'Initialize b??? (FOR: NEXT does this automatically)
DO
e??? = b??? * 2 - 1
a??? = b??? - 1 'Initialize a???
DO WHILE a??? > 0
c??? = ((c??? \ e???) * a???) + f(a???) * %g 'substitute %g for A
e??? = (e??? - 2)
f(a???) = (c??? MOD e???)
a??? = (a??? - 1) 'decrement a???
LOOP
s$ = USING$(u$, d??? + (c??? \ %g))
IF ASC(s$) = 32 THEN MID$(s$, 1) = "0"
PRINT s$; 'same as printf
d??? = (c??? MOD %g)
IF INKEY$ = CtrlBrk$ THEN
EXIT LOOP
END IF
b??? = (b??? - 14) 'Same as FOR: NEXT STEP -14
LOOP UNTIL b??? = 0
PRINT 'same as puts
END
* SLMR 2.1a * MAXLIB For PB v1.1 - Access arrays and files in EMS/XMS!
--- WILDMAIL!/WC v4.12
---------------
* Origin: Com-Dat BBS - Hillsboro, OR. HST DS (1:105/314.0)
|