re: hash implementation: The hashes are implemented directly for
performance.  Performance is improved (over using ConcurrentHashMap) in
several ways:

 - The overhead of segment lookup/reference is eliminated.  CHM breaks a
hash table into segments (default 16) to reduce write contention.  For our
purposes, that doesn't buy much; ivar access will typically be
single-threaded, and constants (usually) and symbols (always) are write-once
(though the symbol table might still benefit from a segmented approach, we
can look at that later).

 - Faster lookups are possible for keys that we know to be interned strings.
I don't have any hard numbers on the percentage of gets/sets that pass
interned strings, but I'd wager it's better than 90% (probably more like
99%), as every name that comes from an AST node is interned.  The
performance benefit is significant.

 - A slightly different lookup algorithm saves one volatile read per lookup
(my approach uses reads/writes to the volatile array field itself [not
entries, the field!] rather than a volatile size field to trigger memory
barriers).

 - A CHECKCAST is avoided for each read.

 - Implementing the tables directly rather than as a component provided a
significant performance benefit -- somewhat to my surprise.  I did
originally take the latter approach.  The code is in
bdortch/attrs/src/org/jruby/runtime/component, in VariableStore (abstract
base class) and ConcurrentObjectVariableStore, which may yet find some use
(in a somewhat modified form) once we refactor IRubyObject/RubyObject.
However, I don't think it's unreasonable to implement these directly for
performance (see RubyArray and RubyHash, for instance).

re: JMM thread, I'll try to find it, it's been a couple of months since I
looked at that stuff.  I think it dated to 2004, or possibly late 2003,
prior to the release of Java 1.5, but around the time JSR-133 was released.
In any case, I'm going to play it safe for now and fall back on the
readValueUnderLock technique.

re: moving internal/special vars to attrs, that should be a goal, though
these are in some cases used only for marshaling.

re: IDs, in the abstract I like the idea, need to see what that means in
concrete terms, what the overhead would be, etc.  In the meantime, I think
the rule can be, when in doubt, don't call the "fast" accessors.  Maybe I
should rename them: scaryFastGetInstanceVariable?

-Bill

Reply via email to