JVM impovements to type checking

Hi, this is my first message to the Scala community.

I’ve been working to improve the runtime performance of the JVM instanceof. I don’t know if Scala utilizes instanceof interface checks for runtime checking, so this post may be irrelevant. However, my first PR changes instanceof checks from O(n) to nearly O(1). Apart from anything else, this can dramatically improve the performance of Java pattern matching switch statements.

So, my question: does this affect Scala? Do you use Java interfaces at all, and do you use instanceof checks on them? One limitation that might be relevant is that my changes so far only benefit classes that implement fewer than 64 interfaces.

12 Likes

Hey thanks for posting, this sounds great!

As for instanceof, A lot of scala code uses the pattern matching idiom, e.g. to break down a scala.List into either :: (cons cell) or Nil (empty list), which is based upon instanceof at runtime. Typically these are class types rather than interfaces, but I imagine there may be a lot of people matching on various mixin interfaces.

e.g. here we can do a different algorithm on a sequence collection by inspecting its runtime type.

def handle(col: Seq[Person]) = col match
  case col: LinearSeq[Person] => // do some linear optimised algorithm
  case col: IndexedSeq[Person] => // do some random-access optimised algorithm

Some more details:

  • Scala traits are always compiled to JVM interfaces, so yes, we do use them.
  • While x instanceof Intf may not be used so much, erasure means that (Intf) x (check_cast) is quite common. If check_cast needs the same run-time type test as instanceof (which I assume to be true), then any improvement directly affects Scala.

Yes, checkcast does use the same logic as instanceof. I did hear that sometimes Scala code uses many interfaces.
The old instance check was horrible once you had 10 or more interfaces. The new one is super-fast for 20 or so interfaces, a little bit slower for 40, and performance tails off after that. I’m guessing that a larger number of traits or interfaces is rare.

20 interfaces is pretty much the common case in the standard collections library. :sweat_smile:

1 Like

20 interfaces is fine. If the number gets way above 40, performance is going to suck. If that’s unlikely or at least really unusual, it’ll be fine.

Thanks for sharing this, will this be backported to java 21? IIRC, In Netty, there are many instanceOf ,eg for Http2Frame testing.