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 <mark_addle...@bigfoot.com> 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 <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.- 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 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 -~----------~----~----~----~------~----~------~--~---