On Tue, May 24, 2011 at 8:28 PM, David Nolen <dnolen.li...@gmail.com> wrote:
> On Tue, May 24, 2011 at 7:54 PM, Ken Wesson <kwess...@gmail.com> wrote:
>>
>> IMO, records should support anything maps support -- in particular,
>> they should support near-arbitrary numbers of entries.
>
> If performance is not a concern I don't see the point of not justing plain
> maps + multimethods. None of these problems apply there.
> On that note, instead of suggesting improvements that would make things
> slower, I'd like to hear people suggest solutions that give the desired
> generality without sacrificing any performance whatsoever. Bonus point if
> the desired solution is actually faster than what we currently have.

The suggestions would make records (and functions) no slower for the
situations where they currently work at all, and would make them work
in situations where they currently fail.

To make them stay fast, without hitting ivar and other limits, you'd
have to do something fundamentally new (and a bit icky): use an array
of Object under the hood to hold the contents/params. There'd still be
a slight penalty for "huge" arglists and records, due to the second
indirection to get from record pointer to array pointer to element in
the case of records, and the indirection to get the arg out of the
array in the case of functions. This also couldn't be done with
deftype (as it would break volatile mutable volatility).

Getting rid of the indirection would require either fundamental JVM
changes (unlikely, at least in the near term) or making records
directly be object arrays "under the hood" rather than deftypes. Then
records aren't their own classes and a lot of how type and .foo
dispatch works for records would have to be changed. Also, records
become thread-unsafe if there's any way to break "hygiene" and
directly get at the array cells to mutate them. I do not recommend
going that far.

Frankly, I'd prefer "large" records just use hash tries. They're
tried, tested, and true (so to speak) and support structure sharing,
unlike anything directly backed by Object arrays. Furthermore, they
won't be any slower to access in the case of <33 fields than Object
arrays and get slower only logarithmically, and it's a very
slow-growing logarithm at that -- in particular, there's only one more
indirection for records with 33-1024 fields. Locality also stays good
(for the field value pointers, rather than the value objects
themselves) for up to 32 fields.

So, one indirection for defined fields in records of up to 20 defined
fields, and for the first 20 defined fields of any record; two for the
next 32 fields of any record; three for the next 992 fields of any
record; past that, seq becomes more efficient for traversal than a
series of direct field accesses that eventually hits them all (and
especially has superior memory locality), and just as efficient as
traversing, say, a vector or a hash-map.

-- 
Protege: What is this seething mass of parentheses?!
Master: Your father's Lisp REPL. This is the language of a true
hacker. Not as clumsy or random as C++; a language for a more
civilized age.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to