What is the portable approach?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

What is the portable approach?

Alan Mead
I have data that would fit an associative array if they really
existed in Pascal, but while the key is a string, the values are
reals [0,1].  So, I have been using a TStringList and something like
(from memory):

MyList.AddObjects('key1',pointer(round(value1*maxint));

I realized that someday I might get burned on a 64-bit machine ...
now (using 2.0) I am reminded of this each time I compile.

So.. what's the portable method?  I could declare a real on the heap
and store the pointer to it.  Or I could write an object to hold the
real and instansiate a new object when I add a record?  Or I could
store the values as text using the psuedo-associate properties of
TStringList?

All these seem clunky... I can esily imagine the first two options
resulting in nasty null pointer run-time errors; they at least double
the amount of space I'm using; and I imagine they will be far slower
(I have a program that spends 20% of it's time allocating little tiny
records on the heap). Using text to store a real seems clearly wrong.

Is one of them the right/accepted/guru way to do it?  Or am I missing
an alternative?  Should I be thinking of extending the TStringList
class?

Thanks!

-Alan
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: What is the portable approach?

L505

>Is one of them the right/accepted/guru way to do it?  Or am I missing
>an alternative?  Should I be thinking of extending the TStringList
>class?

I would think inventing a TStrIntPairList (name can be changed to something else maybe)
would be a good idea if it has not already been invented.

If you think there are advantages to not using classes (procedural better for specific
reasons), then maybe an associative array is in fact needed to be invented for Pascal. I
think the TStrIntPair would be easier to accomplish sooner, since you could just use a
dynamic array of integers and strings wrapped in a class.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: What is the portable approach?

L505
In reply to this post by Alan Mead

> dynamic array of integers and strings wrapped in a class.
>

of course I meant reals not integers
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: What is the portable approach?

Marco van de Voort
In reply to this post by Alan Mead
> I have data that would fit an associative array if they really
> existed in Pascal, but while the key is a string, the values are
> reals [0,1].  So, I have been using a TStringList and something like
> (from memory):
>
> MyList.AddObjects('key1',pointer(round(value1*maxint));
 
(effectively making fixed point coded reals)

> I realized that someday I might get burned on a 64-bit machine ...
> now (using 2.0) I am reminded of this each time I compile.

No, it remains working I think. However you won't increase precision.
(effectively using 31-bit of the 64 bit pointer)
 
> So.. what's the portable method?  I could declare a real on the heap
> and store the pointer to it.  Or I could write an object to hold the
> real and instansiate a new object when I add a record?  Or I could
> store the values as text using the psuedo-associate properties of
> TStringList?

I think abusing a stringlist is bad. Moreover stringlists scale bad if
you stuff more than a 10-20k entries in them.

I have some set and map procedures, but while these are reasonably clean
at the interface level, the implementation is not even close to portable.

However they still have the allocation problem. (value pointer to record with
a real in it).

If you know upfront how many pairs you'll get, you can allocate all
reals together (as array of reals), and store pointers that point to
the values in the array. However be careful to never setlenght or reallocate
the array, since that will fail.

This will save you the allocation performance (runtime) overhead, as well
as the 4 or 8 byte or so heapmgr overhead per allocation, though it
still costs a pointer.
 
> Is one of them the right/accepted/guru way to do it?  Or am I missing
> an alternative?  Should I be thinking of extending the TStringList

Don't. Create an own datastructure that is a true map. Tstringlist and tlist
really shouldn't be used as basetypes for datastructures since they
scale bad.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: What is the portable approach?

Jeff Pohlmeyer
In reply to this post by Alan Mead
AM> I have data that would fit an associative array if they
AM> really existed in Pascal

I remember spotting this in the "Contributed Units" section,
although I don't know if it will suit your needs:
  http://www.behrenhoff.de/pascal/hash.zip
 
.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Re: What is the portable approach?

L505


> AM> I have data that would fit an associative array if they
> AM> really existed in Pascal
>
> I remember spotting this in the "Contributed Units" section,
> although I don't know if it will suit your needs:
>   http://www.behrenhoff.de/pascal/hash.zip
>  




"
    This unit implements an associative array.
    Before writing this unit, I've always missed Perl commands
    like $h{abc}='def' in Pascal.

    Copyright (C) 2001  Wolf Behrenhoff <[hidden email]>
    Version 0.9.1 (works fine, don't know a bug, but 1.0? No,
                   error checks are missing!)
"

Interesting - let us know if it works out.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Re: What is the portable approach?

Alan Mead
--- L505 <[hidden email]> wrote:

>
>
> > AM> I have data that would fit an associative array if they
> > AM> really existed in Pascal
> >
> > I remember spotting this in the "Contributed Units" section,
> > although I don't know if it will suit your needs:
> >   http://www.behrenhoff.de/pascal/hash.zip

[snip]

> Interesting - let us know if it works out.

I really appreciated Jeff's note.  But I think this unit only stores
text strings and values--already better supported, syntactically, by
the psuedo-associative "trick" behavior of string lists:

MyHash := TStrubglist.Create;
MyHash['Alan'] := 'Mead';

I also have to admit being worried by some of the code... like the
lack of error checking (as noted by the author).

-Alan
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Re: What is the portable approach?

Marco van de Voort
> > Interesting - let us know if it works out.
>
> I really appreciated Jeff's note.  But I think this unit only stores
> text strings and values--already better supported, syntactically, by
> the psuedo-associative "trick" behavior of string lists:
>
> MyHash := TStrubglist.Create;
> MyHash['Alan'] := 'Mead';
>
> I also have to admit being worried by some of the code... like the
> lack of error checking (as noted by the author).

Search for decal. It is the only really "generic" container system I know
for delphi.

Of course it lacks performance because of it.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal