Java Performance Enhancement Ideas

(116 comments)

While doing some programming in Java lately I noticed a few mostly easily correctable areas where Java could be faster which I think are pretty easy to fix with minimal backwards compatibility or work to add. I don't really think of these as personal wish-list items but I do think they would solve many performance needs in the community very simply.

Anyhow these are just some odd ideas and I know I don't know all the complexities.

1. Exposing Already Existing JVM Traps to Users

Many JVMs already implement a way to quickly check unlikely conditions such as array bounds indexing and null pointers. Often this is implemented with very low-level mechanisms such as signal-handlers.

Already today I can use a null check instead of a boolean flag to get small but significant speedups in some situations. However, this seems very fragile to me and I'd prefer to have a system library abstracting away such details. As well as segmentation fault handlers another possible implementation strategy is to use a MutableCallSite that points to a constant value. And a normal comparison would also be a valid option on platforms where no better solution can be found.

I feel the simplest API to implement this would be a class (call it Trap for now) that implements a few methods that test a byte to see if they are zero or not.

public final class Trap {
   public boolean checkTrap(byte x);
   public boolean testTrap(byte x) throws TrapException;
   public T onTrapElse(byte x, T onTrap, T onElse);
   // and so on and so forth
}

2. Expose Existing static final Access Semantics as a VarHandle Access Mode

Due to extensive use of reflection in Java frameworks it is difficult for JVMs to optimize final fields of instances. Currently OpenJDK locks away aggressive optimization behind the TrustNonStaticFinalFields flag because otherwise it would break too much code.

My proposal is to expose this as another VarHandle access mode that is weaker than the usual get and set. An access to a static final field is really a read that is reorderable within a thread just as the usual single threaded reads/writes are reorderable between threads.

As a working name call it __GET_FINAL. I feel this is far simpler than any other alternatives and much less likely to break existing code. It would allow application developers to guarantee constant folding very simply and would need minimal changes to implement.

3. Expose Nonaliasable Access Semantics as a VarHandle Access Mode

For a long time C compilers struggled to provide similar performance to languages like Fortran because the unsafe use of pointers caused alias analysis to be very difficult. A workaround was the use of the restrict access specifier which told the compiler reads and writes could be more freely reordered.

Java features a similar if in someways reduced problem when doing optimizations on arrays. I propose a similar weaker VarHandle access semantics that allows the compiler to more freely reorder reads and writes within a method.

As a working name call them __GET_RESTRICT and __SET_RESTRICT.

This could allow for much easier vectorization capabilities in large loops such as:

for (var ii = 0; ii < dest.length; ++ii) {
    var srcVal = SRC.__getRestrict(ii);
    var destVal = DEST.__getRestrict(ii);
    DEST *= SRC: DEST.__setRestrict(ii, val);
}

Clarifying exactly how __GET_RESTRICT and __SET_RESTRICT should work would require careful thought and language lawyering but I believe the fundamental concept is simple enough to understand and has ample precedence in C99.

4. MethodHandles switchCase utility method

The java.lang.invoke.MethodHandles class lacks a switch case combinator and only provides a very primitive guardWithTest combinator. This would be very useful for dispatching across large amounts of method handles and cannot really be emulated with best performance.

// Generate a MethodHandle that takes an int argument that dispatches among the cases.
// Except for performance the result is equivalent to
// filterReturnValue(arrayElementGetter(MethodHandle[].class).bindTo(cases.clone()), exactInvoker(Object.class))
public static MethodHandle switchCase(MethodHandle[] cases); 

Some people do not know this but HotSpot isn't that great at optimising switch cases right now so making this perform well might actually require a lot of work.

5. Thread Local Varhandles

Java ThreadLocals are great for many purposes but a bit too slow sometimes.

VarHandles already provide a fast way to read and write directly into objects.

Suppose we could read and write to fields into the Thread object?

I suggest a static method VarHandle Thread::__newSlot(Class<?> clazz) which dynamically adds a new field to the global Thread class and returns a Varhandle reference to it.

Getting a thread local could then be as fast as a field reference to thread object like MY_THREAD_LOCAL.get(Thread.currentThread());

IMO, the biggest problem is the potential bloating of memory from libraries installing thread locals everywhere. However, this sort of thing is necessary for the next idea.

6. ThreadLocalCallSite

In current Java it is not possible to efficiently dispatch to a different call based on the current thread. You have to resort to hacky techniques such as cloning class methods per core/thread.

If better constant folding optimizations are enabled (see the VarHanlde __GET_FINAL option) than it could be possible to constant fold a MethodHandle from a MutableCallSite's dynamicInvoker which is attached to a Thread as a thread local VarHandle.

Unfortunately getting this working efficiently might require deep reworking of OpenJDK internals because code optimisation is fundamentally based on a global model.

Anyway I hope you thought these ideas were interesting even if you didn't agree with them.

Currently unrated

Comments

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 3 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 2 weeks ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months, 1 week ago

Comment awaiting approval 8 months ago

Comment awaiting approval 8 months ago

Comment awaiting approval 8 months ago

Comment awaiting approval 8 months ago

Comment awaiting approval 7 months, 4 weeks ago

Comment awaiting approval 7 months, 3 weeks ago

Comment awaiting approval 7 months, 3 weeks ago

Comment awaiting approval 7 months, 3 weeks ago

Comment awaiting approval 7 months, 3 weeks ago

Comment awaiting approval 7 months, 2 weeks ago

Comment awaiting approval 7 months, 2 weeks ago

Comment awaiting approval 6 months, 3 weeks ago

Comment awaiting approval 6 months, 2 weeks ago

Comment awaiting approval 6 months, 1 week ago

Comment awaiting approval 5 months, 4 weeks ago

Comment awaiting approval 5 months, 3 weeks ago

Comment awaiting approval 5 months, 3 weeks ago

Comment awaiting approval 5 months, 3 weeks ago

Comment awaiting approval 5 months, 3 weeks ago

Comment awaiting approval 5 months, 2 weeks ago

Comment awaiting approval 5 months, 2 weeks ago

Comment awaiting approval 5 months, 2 weeks ago

Comment awaiting approval 5 months, 1 week ago

Comment awaiting approval 5 months, 1 week ago

Comment awaiting approval 5 months, 1 week ago

Comment awaiting approval 4 months, 4 weeks ago

Comment awaiting approval 4 months ago

Comment awaiting approval 4 months ago

Comment awaiting approval 4 months ago

Comment awaiting approval 3 months, 1 week ago

Comment awaiting approval 3 months, 1 week ago

Comment awaiting approval 3 months, 1 week ago

Comment awaiting approval 3 months, 1 week ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 3 months ago

Comment awaiting approval 2 months, 4 weeks ago

Comment awaiting approval 2 months, 4 weeks ago

Comment awaiting approval 2 months, 3 weeks ago

Comment awaiting approval 2 months, 3 weeks ago

Comment awaiting approval 2 months, 3 weeks ago

Comment awaiting approval 2 months, 3 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 2 weeks ago

Comment awaiting approval 2 months, 1 week ago

Comment awaiting approval 2 months, 1 week ago

Comment awaiting approval 2 months, 1 week ago

Comment awaiting approval 2 months ago

Comment awaiting approval 2 months ago

Comment awaiting approval 2 months ago

Comment awaiting approval 2 months ago

Comment awaiting approval 2 months ago

Comment awaiting approval 2 months ago

Comment awaiting approval 1 month, 4 weeks ago

Comment awaiting approval 1 month, 3 weeks ago

Comment awaiting approval 1 month, 3 weeks ago

Comment awaiting approval 1 month, 3 weeks ago

Comment awaiting approval 1 month, 3 weeks ago

Comment awaiting approval 1 month, 2 weeks ago

Comment awaiting approval 1 month, 1 week ago

Comment awaiting approval 1 month, 1 week ago

Comment awaiting approval 1 month ago

Comment awaiting approval 1 month ago

Comment awaiting approval 1 month ago

Comment awaiting approval 3 weeks, 6 days ago

Comment awaiting approval 3 weeks, 2 days ago

Comment awaiting approval 1 week, 6 days ago

Comment awaiting approval 1 week, 6 days ago

Comment awaiting approval 1 week, 1 day ago

Comment awaiting approval 2 days, 18 hours ago

Comment awaiting approval 1 day, 4 hours ago

Comment awaiting approval 1 day, 4 hours ago

New Comment

required

required (not published)

optional

required