Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How big class hierarchy influence on java performance?

I have class that extends another class, that extend another class.. and so on.

How slow (in percent) class with 100-level hierarchy level will work, then class with 10-level hierarchy level?

like image 838
qwazer Avatar asked Feb 17 '11 11:02

qwazer


2 Answers

Let's try it out:

class T1 {}
class T2 extends T1{}
class T3 extends T2{}
class T4 extends T3{}
class T5 extends T4{}
class T6 extends T5{}
class T7 extends T6{}
class T8 extends T7{}
class T9 extends T8{}
class T10 extends T9{}
class T11 extends T10{}
class T12 extends T11{}
class T13 extends T12{}
class T14 extends T13{}
class T15 extends T14{}
class T16 extends T15{}
class T17 extends T16{}
class T18 extends T17{}
class T19 extends T18{}
class T20 extends T19{}
class T21 extends T20{}
class T22 extends T21{}
class T23 extends T22{}
class T24 extends T23{}
class T25 extends T24{}
class T26 extends T25{}
class T27 extends T26{}
class T28 extends T27{}
class T29 extends T28{}
class T30 extends T29{}
class T31 extends T30{}
class T32 extends T31{}
class T33 extends T32{}
class T34 extends T33{}
class T35 extends T34{}
class T36 extends T35{}
class T37 extends T36{}
class T38 extends T37{}
class T39 extends T38{}
class T40 extends T39{}
class T41 extends T40{}
class T42 extends T41{}
class T43 extends T42{}
class T44 extends T43{}
class T45 extends T44{}
class T46 extends T45{}
class T47 extends T46{}
class T48 extends T47{}
class T49 extends T48{}
class T50 extends T49{}
class T51 extends T50{}
class T52 extends T51{}
class T53 extends T52{}
class T54 extends T53{}
class T55 extends T54{}
class T56 extends T55{}
class T57 extends T56{}
class T58 extends T57{}
class T59 extends T58{}
class T60 extends T59{}

I was able to instantiate T53, but T54 onwards threw a StackOverflowError.

new T54();

Exception in thread "main" java.lang.StackOverflowError
    at java.lang.ref.Reference.<init>(Reference.java:216)
    at java.lang.ref.FinalReference.<init>(FinalReference.java:16)
    at java.lang.ref.Finalizer.<init>(Finalizer.java:66)
    at java.lang.ref.Finalizer.register(Finalizer.java:72)
    at java.lang.Object.<init>(Object.java:20)
    at java.io.InputStream.<init>(InputStream.java:28)
    at java.io.FileInputStream.<init>(FileInputStream.java:96)
    at sun.misc.URLClassPath$FileLoader$1.getInputStream(URLClassPath.java:1005)
    at sun.misc.Resource.cachedInputStream(Resource.java:61)
    at sun.misc.Resource.getByteBuffer(Resource.java:144)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:256)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

This was done using the default JVM stack size.

For a 100-level hierarchy you will need a larger stack. (You can increase your stack size using Xss.)

like image 71
dogbane Avatar answered Oct 28 '22 04:10

dogbane


"Good JVMs" (whatever that means) cache the results of method resolution. Performance impact therefore should occur only once and even that will likely be minimal. However, on object creation time an instance of every extended class will be created too every constructor of every superclass will be called, which might result in a bigger impact when creating a lot of objects that have large hierarchies.

I have to concur with Jon Skeet (well, who doesn't) in that the question sounds like there are some serious design issues or a code generator gone rogue. It's akin to asking "how many columns does a database table support". If it's more than reasonable, you're probably doing it wrong.

like image 42
musiKk Avatar answered Oct 28 '22 02:10

musiKk