TIP: Click on subject to list as thread! ANSI
echo: z3_pascal
to: Colin Gunningham
from: Ian Smith
date: 1996-05-23 11:41:54
subject: StringToInteger

CG> I think a set might use a fixed number of bytes regardless of
 CG> the number of elements you use. perhaps you should look into
 CG> other methods of testing each value...

Nope, sets use as many bytes as are needed; set of [0..7] is a byte, etc. 
A set of ['A'..'Z'] is stored in 26 bits, using just 4 bytes.  The
equations for accessing the nth bit of a set are in the manual, somewhere
..

 BL> I tried using an array and a set constant but it was slower. A set
 BL> is really fast! I was actually surpised... so easy and so fast. I
 BL> thought programmers had a law against that.

I had a look at some compiled set handling code back a while ago.  I was
quite surprised that Frank thought it so poor; I actually found it pretty
nifty, and fast, though I was looking at smallish sets (byte, word, longint
size) mostly.

 CG> I was thinking of maybe stuff like a case sequence
 CG> for your '0' to '9's sort of thing, 'spose you've tried it :)

Searching a set using bitmasks is _much_ faster than any case tests, which
are in effect about the same as a bunch of 'if .. else if' tests.  The
syntax is a bit wierd, but adding and subtracting set elements works well,
pretty quickly.  Here's an edited snippet from my BTUNEVT.PAS:

type
   day = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
   dayset = set of day;            { bits 0 .. 6 }

var
   days : dayset; { byte } { from a record - Bit field for days to execute }
   d    : day;

const
   dayname : array [day] of string[3] =
                ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');

   wkdays  : dayset = [Mon..Fri];
   wkndays : dayset = [Sat, Sun];
   alldays : dayset = [Sun..Sat];

[..]
      if days = alldays then cstr := 'All'
      else begin
         if wkdays <= {is a subset of} days then begin
            cstr := 'Week';
            days := days - wkdays
         end
         else if wkndays <= days then begin
            cstr := 'WkEnd';
            days := days - wkndays
         end
         else cstr := '';

         for d := Sun to Sat do
            if d in days then begin
               if cstr  '' then addstr (cstr, '|');
               addstr (cstr, dayname [d]);
               days := days - [d]
            end
      end;

 CG> Maybe storing the Ord() - 48 values in a lookup table could
 CG> speed things up ?

Dunno.  Ord and Chr are simply casts, to keep the compiler happy re types;
they don't generate any code at all.  Subtraction is probably cheaper than
table lookup, but I'll be interested to hear the comparisons.

 BL> I don't know what you mean. Now I'll have to look up lookup tables
 BL> (grin). I thought a set was a table.

 CG> well I keep seeing that math calculation happening again
 CG> and again: Ord(p^) - 48;

load [p], subtract 48; pretty straightforward stuff for a micro ..

 CG> I forget how set's are stored, but a lookup table would be an
 CG> array of all your values for Ord ('0'..'9') - 48, precalculated.
 CG> worth checking out which combinations are faster

Yep, remembering that a set of ['0'..'9'] is 10 bits, stored in 2 bytes.

 BL> Ord() is very fast. I couldn't find a way to get an integer quicker.

Ord is better than fast - it's instantaneous :)

Cheers

--- MaltEd 1.0.b5
* Origin: Magic Puddin' BBS Nimbin 066-89-1843 V.32bis/V.42 (3:626/660)
SEEN-BY: 633/267 270
@PATH: 626/660 711/401 808 50/99 635/544 727 633/267

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.