[comp.lang.icon] table initialization

cargo@TARDIS.CRAY.COM (David S. Cargo) (02/02/90)

I was looking at implementing some Icon code to initialize font width
tables.  Naturally I thought about using tables to do this.  I then
realized that while most other structures can be initialized with
constants, there doesn't seem to be a convenient way to do this with
tables.  Or is there something I'm missing.

What I will probably wind up doing is either using lists indexed by
character values (using ord(s)) or using two constant lists to
initialize a table, char_val and char_width are the two lists:

every i := 1 to n do width[char_val[i]] := char_width[i]

Eventually I'll probably want to know which is faster to use, a
character width table or and array indexed using ord(s))

string_width := 0 # for either case
every string_width +:= char_width[ord(!s)] # for a list
every string_width +:= char_width[!s] # for a table

It would seem to be a trade between ease of access and creation
of temporaries.

Has anybody tried anything like this already and found an answer
to which is better speed-wise?

wgg@CS.WASHINGTON.EDU (William Griswold) (02/02/90)

>From: cargo@tardis.cray.com (David S. Cargo)
>To: icon-group@cs.arizona.edu
>Subject: table initialization
>
>I was looking at implementing some Icon code to initialize font width
>tables.  Naturally I thought about using tables to do this.  I then
>realized that while most other structures can be initialized with
>constants, there doesn't seem to be a convenient way to do this with
>tables.  Or is there something I'm missing.
>
>What I will probably wind up doing is either using lists indexed by
>character values (using ord(s)) or using two constant lists to
>initialize a table, char_val and char_width are the two lists:
>
>every i := 1 to n do width[char_val[i]] := char_width[i]
>
>Eventually I'll probably want to know which is faster to use, a
>character width table or and array indexed using ord(s))
>
>string_width := 0 # for either case
>every string_width +:= char_width[ord(!s)] # for a list
>every string_width +:= char_width[!s] # for a table
>
>It would seem to be a trade between ease of access and creation
>of temporaries.
>
>Has anybody tried anything like this already and found an answer
>to which is better speed-wise?
>

You might want to think about storing your character set and font widths
in an external file, so that if the values (i.e., font) change, you won't
have to change your program.  Then the code for tables vs. lists is not
so different:

Your input:

a	5
b	5
...
m       8
...
z       6

the processing code:

# e.g., for tables
table := width()
while line := read(font-file) do 
    line ? width[move(1)] := integer((tab(many(' \t')) & tab(0)))


As for performance, there are several things you can try.  It is likely
that the ord(s) function will be faster, since the hashing and chaining
used to implement tables will be avoided.

If you want to hide which type you are using, use a procedure.  Procedure
call is pretty cheap, so you don't have to worry much about the cost: 

# for tables
procedure width(char)
static width-table
initial width-table := table()

    return width-table[char]
end


# for lists
procedure width(char)
static width-list
initial width-list := list(256)

    return width-list[ord(char)]
end

Note that since I didn't dereference the return variable, they can be
assigned to by the input function:

    while line := read(font-file) do 
	line ? width(move(1)) := integer((tab(many(' \t')) & tab(0)))

Thus even the font width reader doesn't need to know the representation
you are using.

One thing that just occurred to me is that with the table representation
(or some hybrid enscapsulated in a procedure) you could look-up word
widths as well as character widths, probably at little extra effort (say,
if you stored the widths of the 2000 most commonly used words) and some
performance benefit.  You could even use a history scheme, in which you
remember the widths of words already computed in the current document.  It 
seems like overkill, but it gives you some idea of the flexibility of Icon. 

					Bill Griswold

cargo@TARDIS.CRAY.COM (David S. Cargo) (02/02/90)

"You might want to think about storing your character set and font widths
in an external file, so that if the values (i.e., font) change, you won't
have to change your program."

As a matter of fact, I will start by reading the Adobe Font Metrics file
to get the initial values.  I could either use them directly, or have
the program write initialization code to be used by another program.
It's a matter of early or late binding in effect.  If you think that
ord(s) is fast relative to hashing, I'll probably go that way.

david snail