blackdrag at gmx.org
Mon Jul 13 14:41:46 PDT 2009
John Rose schrieb:
> On Jul 13, 2009, at 12:04 PM, Jochen Theodorou wrote:
>> [boxing] is a problem we should discuss for invokedynamic in more
>> Especially how to go around that problem to get maximum performance.
>> What do you think?
> I might be missing your point, Jochen, but I think we need a three-
> point approach:
my point is, that in a a=b+c (all being int or Integer) Groovy is
currently having two Integer, that are used to call a plus method, which
unboxes those and boxes the result again to have an return value.
Compared to the usage of Integer this means two times unboxing, and one
time boxing. Compared with native ints this means two times boxing for
the method call, two times unboxing for the normal plus, one time boxing
for the result and one time unboxing for the variable. That is 3 times
unboxing and boxing that reduce performance quite a bit. Assuming the
unboxing is not expensive, that leaves 3 boxing actions. Using Integer
this is still 1 boxing action. I have plans for Groovy to let it use
primitive ints with a primitve int using plus method or even direct
bytecode to make groovy faster for those things. But that decision also
depends a bit on how invokedynamic will proceed.
> 1. Make boxing/unboxing less common, by supporting primitives in JSR
> 292. This point applies to all sizes and shapes of JVMs. It requires
> more smarts in the language implementation, but some languages (e.g.,
> CAL) already optimize primitive arguments, since the JVM rewards it.
> 2. Make some cases of boxing/unboxing cheaper, by supporting fixnums.
> This point applies to all sorts of JVMs, but is not widely in use.
> There is an empty mlvm project for this, and it will probably see some
> activity, at least for Integer.valueOf specifically. (Any takers?)
> 3. Make some cases of boxing/unboxing optimizable, by including strong
> escape analysis in the JIT, including Integer.valueOf. This point
> only applies to JVMs with full-power JITs, and requires some special
> pleading for Integer.valueOf, because of its interning behavior.
Hmm maybe here the tight integration with java becomes a problem. We
have all the interger types Java has too, and they have the same meaning.
The goal is to reach the same (well almost) performance as native Java
of course. Any boxing/unboxing there will have a very negative effect on
the performance level.
Way 3 could be the most easy way for us, but it depends on the actual
usage. If we had to move our object based math to primitive type math,
we would have loads of additional code in the groovy runtime for special
cases, but then we can avoid boxing completely, so we would not really
need that way anyway. The downside, that we cannot use invokeDynamic
here is of course still there. A sample implementation would have to
show if it is worth the effort. Well.. cannot use invokedynamic on my
Way 2 is a big change and I am not yet sure how much of it can be used.
Assuming Fixnums are kind of objects, then we have to provide additional
type information since those fixnums would represent chars, bytes,
ints and longs at the same time. To say the truth, I cannot yet imagine
the actual usage at the moment very much, so nor sure about the real
restrictions. Also if we have to "create" a fixnum with the same costs
as an object, then it is probably not worth the effort, since a a+b
would then involve creating a new fixnum. Even if that costs only as
much as creating an Integer using valueOf (which makes not really a big
difference on my machine) it is not worth the effort. It has to be
cheaper, preferable much cheaper. But even then we may decide to change
to native math, since that is still faster. So it needs to be just as
fast, including the JIT inlingin and replacing code!
For way 1 I thought that maybe multiple boostrap methods will be
supported, so whatever is needed can be used. Not sure if that would be
a big project.
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
More information about the mlvm-dev