Как большая иерархия классов влияет на производительность Java? - PullRequest
8 голосов
/ 17 февраля 2011

У меня есть класс, который расширяет другой класс, который расширяет другой класс ... и т. Д.

Как медленно (в процентах) будет работать класс с уровнем иерархии 100 уровней, затем класс с уровнем иерархии 10 уровней?

Ответы [ 4 ]

11 голосов
/ 17 февраля 2011

Давайте попробуем это сделать:

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{}

Мне удалось создать экземпляр T53, но T54 выдал 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)

Это было сделано с использованием размера стека JVM по умолчанию.

Для 100-уровневой иерархии вам понадобится больший стек.(Вы можете увеличить размер стека, используя Xss.)

8 голосов
/ 17 февраля 2011

«Хорошие JVM» (что бы это ни значило) кэшируют результаты разрешения метода.Следовательно, влияние на производительность должно происходить только один раз, и даже оно, вероятно, будет минимальным.Тем не менее, во время создания объекта будет создан экземпляр каждого расширенного класса. будет вызван каждый конструктор каждого суперкласса, что может привести к большему воздействию при создании большого количества объектов.которые имеют большие иерархии.

Я должен согласиться с Джоном Скитом (ну, а кто нет) в том, что вопрос звучит так, как будто есть некоторые серьезные проблемы с дизайном или из-за того, что генератор кода вышел из строя.Это похоже на вопрос «сколько столбцов поддерживает таблица базы данных».Если это больше чем разумно , вы, вероятно, делаете это неправильно.

7 голосов
/ 17 февраля 2011

Это будет зависеть от вашей JVM, точных операций, которые вы выполняете, от переопределения различных методов и т. Д.

Однако я был бы гораздо больше обеспокоен влиянием дизайна и читабельности, чем влиянием на производительность. Это действительно лучший дизайн, который вы можете придумать? Какую проблему она решает, которая не может быть лучше решена другим способом?

3 голосов
/ 17 февраля 2011

Согласно Java2 Полный справочник Автор Герберт Шильдр:

Однако вы можете унаследовать любое класс, уровень наследования классов Java более 5 не более заметно. это всегда будет снижать производительность.

Я также согласен с ответом Джона Скита.

...