On Sat, Jun 12, 2010 at 3:53 PM, Ola Bini <ola.b...@gmail.com> wrote:
> I do see the need to make these kind of changes, based on their performance
> impact. But I still have reservations (maybe because I'm one of the people
> who write code that usually sets instance variables on Java objects, and
> opens up the metaclass.) Specifically, these features are very useful in
> testing, for example. However, I guess that can still be done by using the
> enable_object_features on the framework side, although that feels a bit
> ugly.

The other possibility would be to detect when a method that sets
instance variables, but that's less reliable. We would have to be able
to see into the code and flip the "enable_object_features" bit at that
point, and it would only affect future instances.

I sympathize with wanting to keep the feature available and not make
it onerous, and I'm open to suggestions for better ways to do it.
Always providing idempotent wrappers permanently hinders Java call
performance.

> I am uncomfortable with not making any guarantees the wrapper will be the
> same. That will lead to lots of silent failures far away from where the
> point of the problem which will be extremely hard to track down for people.
> I would prefer it if we just stopped doing it period, without the
> enable_object_features call. I think that would make the transition easier.

If you don't use instance vars or singletons the fact that there are
different wrappers is almost entirely transparent. Other than object
identity operations against the wrapper it's almost impossible to tell
from Ruby whether you have one wrapper or another. On the positive
side, creating new wrappers is much cheaper than either adding
creating a wrapper and adding an entry to our weak map. It's even
faster than looking up an existing wrapper!

~/projects/jruby ➔ jruby -rjava -rbenchmark -e "5.times { a =
java.util.ArrayList.new; o = java.lang.Object.new; 1_000_000.times {a
<< o}; puts Benchmark.measure { iter = a.iterator; while
iter.has_next; iter.next; end } }"
  0.668000   0.000000   0.668000 (  0.643000)
  0.623000   0.000000   0.623000 (  0.623000)
  0.643000   0.000000   0.643000 (  0.643000)
  0.622000   0.000000   0.622000 (  0.622000)
  0.644000   0.000000   0.644000 (  0.643000)

~/projects/jruby ➔ jruby -J-Djruby.ji.objectProxyCache=false -rjava
-rbenchmark -e "5.times { a = java.util.ArrayList.new; o =
java.lang.Object.new; 1_000_000.times {a << o}; puts Benchmark.measure
{ iter = a.iterator; while iter.has_next; iter.next; end } }"
  0.642000   0.000000   0.642000 (  0.613000)
  0.587000   0.000000   0.587000 (  0.587000)
  0.584000   0.000000   0.584000 (  0.583000)
  0.589000   0.000000   0.589000 (  0.589000)
  0.594000   0.000000   0.594000 (  0.594000)

As you say, not wrapping objects at all is better than wrapping them
with a new object every time, and that's where we want to go. But to
get there we need to start moving away from supporting instance vars
and singletons out of the box.

I'm fairly confident that with my recent dynopt work, if we eliminated
wrappers I could get Ruby to Java calls to basically just be static
Java calls in bytecode.

- Charlie

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to