Actually, you probably wouldn't want to use an array. Instead, cache
could be made up of IPrimitiveHolder objects:
public interface IPrimitiveHolder {
public java.lang.Object toBoxedObject();
public int toChar();
public int toByte();
public int toInt();
...
}
On Aug 4, 8:06 am, Mark Addleman <[email protected]> wrote:
> Whoops, submitted that a bit too soon.
>
> I guess only couple of things to add:
>
> (1) The cost of obtaining the primitive array and returning it to the
> cache is likely no worse than operations on an ArrayList, so those
> should be very cheap.
>
> (2) The cost of coercing the primitive to a java.lang.Number is
> likely no worse than the cost of standard Java boxing.
>
> What do people think? Those of you familiar with the Clojure
> compiler, does this approach make sense?
>
> On Aug 4, 8:02 am, Mark Addleman <[email protected]> wrote:
>
>
>
> > I think there may be a somewhat straightforward solution to improving
> > Clojure's performance when passing primitives between functions.
> > Here's my understanding of the problem: The IFn interface is a series
> > of invoke method signatures that take a number of java.lang.Objects as
> > parameters and returns a java.lang.Object. Primitives can't be passed
> > this way and it would be a silly explosion of code to create the
> > methods signatures in IFn that included primitives. The performance
> > characteristcs of "boxing" primitives relies on the JVM's performance
> > of allocating and deallocating objects.
>
> > My analysis: The JVM is awfully good at handling transient objects
> > like the ones used for boxing, but no matter how good it is, it's
> > always better if the work needn't be done in the first place.
>
> > Here's my notion (bordering on brain fart): Clojure does its own
> > primitive boxing using one element arrays. Each thread has a
> > dynamically growable threadlocal cache of one-element arrays for each
> > primitive that needs to pass through the stack. At the call site, the
> > compiler generates code to "allocate" the one element array
> > threadlocal of the appropriate type and stuffs the primitive into the
> > array. Since the array itself is a java.lang.Object, it can pass
> > through the IFn interface without a problem. At the target site, it
> > gets a bit more tricky. If the object is type-coerced to a primitive,
> > it's simply a matter of pulling the first (and only) element out of
> > the array. If the object is treated as a java.lang.Number, Clojure
> > must create the correct java object on the fly. I don't think this
> > logic is very hard, but I can see how it might get tricky and have
> > lots of cases depending on how the compiler is designed.
>
> > Once the threadlocal cache is of sufficient size (I *think* the
> > largest it ever needs to grow is the largest number of primitives in
> > any method signature), the boxing costs fall into two categories: In
> > the case where the object is coerced to a primitive, no tax is placed
> > on the garbage collector. The cost is obtaining an available
> > primitive array, stuffing the primtive into the array, reading the
> > primitive out of the array and putting the array back into the cache.
> > This should be substantially faster than standard Java boxing. In the
> > case where the object is treated as a java.lang.Number, the cost is
> > obtaining an available primitive array, stuffing the primtive into the
> > array, constructing the appropriate object and returning the the array
> > to the cache.- Hide quoted text -
>
> - Show quoted text -
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---