Dan,
As it stands, KEY * is a win when: 1) All of the array indices are constants and hardcoded into the instruction stream 2) The PMC handling the index does not have to recurse. In all other cases, as it currently stands, it is a loose. I hate to come out and be so blunt, but I think this is the culmination of what I've found, and a lot of people are saying. This approach is penny wise, pound foolish. 1) KEY *'s and their atoms are allocated from memory. The memory allocation hurts more than it saves, cycle wise. The number of CPU cycles used doing a virtual machine instruction *pales* in comparison to what is needed to allocate memory. 2) Constants are very seldom used as array indexes, in real code, and almost never used exclusively in multidim access. If you had an x*y*z sized array, it would take x*y*z statements to access all of its members! Thats hardly an expressive language =) 3) When several PMCs recurse to handle a KEY * request, the system stack has everything pop'd off and back on once for each member of the KEY * list! If nothing else, refactor this into an iterative thing rather than recurisve thing! Create a register that holds KEY * and for gods sake, get everything off the system stack. Given your objectives of speed, generality and elegance, I could propose several other solutions: 1. PMCs spit out an "inner class" of themselves on demand, that are attached to the scalars and arrays that index their parents. When this child PMC is accessed, the value indexed by the indices we reference is accessed instead. As a container, it is immutable. Reference to the indicing PMCs is dropped when we go out of scope or are destroyed. Given: $a = $b->[$x]->[$y]->[$z], a $b_delta would be created that could be accessed directly: $a = $b_delta. $b_delta would be attached to $x, $y, $z. This optimizes cases where the same variables index a multidim, even as their values change. This is a real-world case that would have real benefits. Put another, it would be like converting: $ob->accessor($x, $y, $z) into $new_accessor = sub { ob_accessor($x, $y, $z) } allowing you to say $new_accessor->(), omiting $x $y $z, but would be a performance gain instead of loss =) 2. PMCs return iterators allocated on a stack that allow them to function as KEY *s allocating a single fixed size peice of memory rather than all of the parts of a linked list. In other words, factor out the part of PMCs that index a given element. This would completely bypass the construction of KEY* lists, and allow PMCs to function as keys. This case needs to be optimised, as most keys will be scalars or a few scalars, and quickly moving from a scalar to a key should be paramount. 3. Let PMCs create KEY * lists. Whats more, rather than scraping KEY * lists of an adequate size and replacing them every iteration in user code loops, *update* the KEY* list from PMCs. Eg, if $x is the first item, $y is the second, and $z is the third, update the values in the KEY* with the new values from the scalars, then shuffle the same KEY * off again. Use a load/store strategy! The complexity involved in exposing every single method in a contained object damages cache use beyond *any* possible benefit! See earlier post for details. General Philosophical Diatribe: * count cycles * count resources * complexity in name of speed should be very carefully scutinized * follow malloc() through a debugger sometime - you'll never want to use it again case in point, p6 overallocates whereever it can to avoid it in the future * function calls consume resources * assuming a 2 meg cache on a 2 meg cache makes for a program that works *great* on your machine, then proceds to suck pond scum on mine =) assuming a 1 meg cache, the program will run marginally slower on yours, but an order of magnitude faster on mine * caches, virtual memory, and all of their ilk work best when you pretend they dont exist. think of them as little faerie helpers - dont demand work, and when your shoes are fixed in the morning, leave them a treat ;) Case in point: Perl 5 runs *awesome* on a 486/25. Java (Kaffe) is completely unusable. AWT windows come up in a matter of *days*, whereas a Tk window comes up in about 45 seconds. On a fast computer, these things are blurred. The point is, you can thrash your system on a faster computer, but register renaming, a large L2 cache, lots of disc bandwidth to thrash with etc obscured the fact that you are wasting resources horribly. In summary, I beg Dan to reconsider =) -scott On Sun, 21 Jul 2002, Dan Sugalski wrote: > At 6:58 PM +0200 7/21/02, Josef Höök wrote: > > > >That looks something similar what i've been thinking of. If we go further > >in this thinking why not make KEY , INTVAL , NUM and PMC all pmc's > >and just call set and get on pmc's. > > Speed. The reason for them is speed. Generality and elegance are > nice, but the point is to go faster, which is why the special cases > are there. > -- > Dan > > --------------------------------------"it's like this"------------------- > Dan Sugalski even samurai > [EMAIL PROTECTED] have teddy bears and even > teddy bears get drunk > >