On Aug 4, 8:21 am, Rich Hickey <richhic...@gmail.com> wrote:
> On Tue, Aug 4, 2009 at 11:02 AM, Mark Addleman<mark_addle...@bigfoot.com>
> 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.
>
> This approach is doomed on so many fronts.
>
> First, there is zero reason to believe your arrays will be any more
> efficient than Integer etc.
>
> Second, the caching is a barrier to escape analysis. Since rather than
> seeing a freshly-boxed integer 42, which can be optimized away, the
> compiler sees a branch into cache lookup code that returns something
> the compiler cannot know, thus it can't get rid of the lookup. Cliff
> Click sees this problem today, with Integer/valueOf(int), which does
> caching.
>
> etc
>
> FYI, I'm going with the "silly explosion of code to create the methods
> signatures in IFn that included primitives", since the only 2
> primitives one needs to support are long and double.
>
> Stay tuned...
>
> Rich- Hide quoted text -
>
> - Show quoted text -
In that case, disregard previous transmission :)
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---