Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2005-09

What is the portable approach?

8 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

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

Marco van de Voort
to Alan Mead
Show quoted text 6 lines
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)

Show quoted text 5 lines
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.

L505
to Alan Mead: I have data that would fit an associative array if they really existed in Pascal, but…
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.

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

of course I meant reals not integers

L505
to Jeff Pohlmeyer
Show quoted text 7 lines
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
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.

Alan Mead
to L505
--- L505 wrote 8 lines
> 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

Marco van de Voort
to Alan Mead
Show quoted text 11 lines
> 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.