Wie viel Prozess- und Speicherverbrauch nimmt das Casting in Java?

8

Ich überlege, ob es besser ist, zwei Zeiger zu haben, einen für jede Objekt-Unterklasse und super, oder ob ich nur Casting verwenden soll.

Wieviel Systemressourcen verwendet dies:

%Vor%

Ist es besser als:

%Vor%

Grundsätzlich geht es bei meiner Hauptfrage um die Ressourcen, die beim Casting verwendet werden, im Gegensatz zu einem zusätzlichen Zeiger. Es scheint, als könnte ich mehrere Inline-Casts speichern, wie zum Beispiel:

%Vor%

Aber ist es das wert?

Danke, Danke Grae

UPDATE:

Es gab einige unklare Teile meiner Frage. Grundsätzlich habe ich eine super Klasse, die ich durch eine große Funktion verwende. Es funktioniert mit drei Unterklassen. Einige der Super-Klasse funktioniert, wie ich möchte. Allerdings treffe ich an einigen Stellen eine Straßensperre, wo ich eine Funktion aus einer der drei verschiedenen Unterklassen benutzen muss; eine Funktion, die nur in einer der Unterklassen ist.

Ich könnte einfach haben:

%Vor%

oder ich könnte haben:

%Vor%

Allerdings weiß ich nicht, welches effizienter ist.

UPDATE 2:

Hier ist ein Beispiel, um Ihnen zu zeigen, worüber ich spreche:

%Vor%

Das Zwei-Zeiger-Beispiel: (Nach unten ein extra Zeiger.)

%Vor%

Oder ich könnte es so machen. (Downside eine Reihe von Casts.)

%Vor%

Sind also fünf Würfe schlimmer als ein zusätzlicher Zeiger? Was war das für sechs Würfe oder 20? Ist eine Besetzung schlechter als der Zeiger.

Grae

    
GC_ 19.10.2010, 13:35
quelle

6 Antworten

11

Aus Ihrem Code-Snippet geht hervor, dass getSameInstance() eine SubClass zurückgibt. In diesem Fall ist die einfachste Lösung

%Vor%

Kein Guss, keine Sorgen: -)

Wie andere zu Recht angemerkt haben, sollte das Hauptanliegen die Lesbarkeit und Einfachheit des Codes sein, nicht die Leistung. Optimieren Sie nur, wenn Sie wissen, dass Sie den Engpass in Ihrem Code verwenden müssen (und einen Profiler verwenden). Selbst in diesem Fall ist eine Mikrooptimierung in Java selten sinnvoll.

Eine zusätzliche Anmerkung: Wenn Sie die gleiche Methode zweimal aufrufen, kann das problematisch sein, wenn die Methode schwer ist (in diesem Fall wird Ihr Code langsamer, nicht schneller) oder hat Nebenwirkungen (in diesem Fall das Verhalten Ihres Programms) merklich ändern).

Und in dieser Zeile Ihres Code-Snippets

%Vor%

Es ist absolut nicht notwendig, den zurückgegebenen Wert auf SuperClass zu aktualisieren - eine Superklassenreferenz kann immer auf ein Unterklassenobjekt zeigen. (Ich denke, dass ein solcher Upcast ohnehin vom Compiler weggelassen wird, so dass es im Bytecode keinen Unterschied macht.)

Aktualisieren

Sie haben die Deklaration der von mir geforderten Methode noch immer nicht veröffentlicht. Aber von Ihrer Erklärung nehme ich an, dass es ungefähr wie

aussehen sollte %Vor%

ist das korrekt?

Das würde bedeuten, dass Ihr 2. Code-Snippet (mit dem getSameInstance() -Aufruf) falsch ist - die Casts sollten genau umgekehrt sein. Du hast es geschafft, mich damit zu verwirren, also hast du eine verwirrende Antwort: -)

Auch in den letzten Beispielen müssen Sie den zurückgegebenen Wert nicht in (Shape) umwandeln, da dies bereits ein Shape ist. Die Besetzung überschwemmt nur deinen Code. In ähnlicher Weise machen die vielen Umwandlungen im zweiten Beispiel Ihres UPDATE 2 den Code schwer lesbar. Ich würde die erste Version bevorzugen, mit zwei Referenzen ( nicht Zeiger btw - Java hat keine Zeiger).

Und ich kümmere mich hier nur um die Lesbarkeit des Codes - wie andere schon bemerkt haben, sollten Sie wirklich, wirklich keine Zeit damit verschwenden, über die Kosten von Güssen nachzudenken . Konzentrieren Sie sich darauf, Ihren Code so einfach und lesbar wie möglich zu gestalten. Sie würden höchstwahrscheinlich nie den geringsten Unterschied zwischen der Leistung der beiden oben gezeigten Code-Snippets bemerken (außer vielleicht, wenn sie millionenfach in einer engen Schleife ausgeführt werden - aber dann würde das JIT vermutlich optimieren das wirft sowieso weg). Sie werden jedoch den Unterschied feststellen, den es braucht, um ein Code-Snippet im Vergleich zu dem anderen zu verstehen, für jemanden, der neu in diesem Code ist - oder jemand, der die Details bereits vergessen hat, was in etwa 6 Monaten sein könnte.

>     
Péter Török 19.10.2010, 13:38
quelle
20

Machen Sie den Code klarer, vergessen Sie die Mikrooptimierungen.

    
Michael Borgwardt 19.10.2010 13:38
quelle
3

Casting ist keine "Operation", die zur Laufzeit ausgeführt wird. Es wird nur vom Compiler benötigt, um die Sicherheit des statischen Typs sicherzustellen.

Betrachtet man nur JVM-Code, sind die beiden Ansätze im Grunde äquivalent, sie sind implementiert als

%Vor%

Es ist also ein kleiner Overhead vorhanden, aber es ist in beiden Fällen dasselbe (da du sowieso einen Downcast machen musst).

    
Jack 19.10.2010 13:38
quelle
2

Lesbarkeit und Code-Pflege sollten in so etwas Priorität haben, nicht in der Leistung, es sei denn, Sie treffen tatsächlich auf einen Engpass (extrem unwahrscheinlich).

Es gibt jedoch keinen Grund, zwei Referenzen (Zeiger) zu haben. Verweise einfach auf die Unterklasse. Alles, was Sie mit der Oberklassenreferenz tun können, können Sie in fast allen Fällen mit der Unterklassenreferenz tun (ein Parameter für eine überladene Methode ist die einzige Ausnahme, die ich kenne).

    
Yishai 19.10.2010 13:39
quelle
1

Gehen Sie einfach mit der Lösung, die einfacher zu lesen und sauber zu halten ist (wahrscheinlich die erste Lösung). Bei dieser niedrigen Optimierungsstufe lohnt es sich wirklich nicht, außer in Randfällen, in denen Sie wirklich die zusätzliche 0,01% ige Leistungsverbesserung benötigen.

Für das, was es wert ist, müssen Sie eigentlich keine Unterklasse in eine Superklassenreferenz (zweite Lösung aufgelistet) umwandeln, nur umgekehrt. Wenn Sie eine Superklasse in eine Unterklasse umwandeln, ist es im Allgemeinen vorzuziehen, den Typ mit instanceof vor dem Cast zu überprüfen, anstatt Annahmen zu treffen.

    
Ophidian 19.10.2010 13:38
quelle
0

Nehmen wir an, Sie haben eine 64-Bit-Maschine und sparen 8 Byte an Ressourcen. Nehmen wir an, Sie haben 10 Minuten darüber nachgedacht. War es eine gute Nutzung Ihrer Zeit?

1 GB addiert ungefähr $ 100 zu den Kosten eines Servers, also kosten 8 Bytes ungefähr $ 0.0000008

10 Minuten Ihrer Zeit sind etwa 1 Dollar Mindestlohn wert.

Die Ressource ist wiederverwendbar, Ihre Zeit ist nicht verfügbar. Noch wichtiger ist, dass die Zeit, in der jemand Ihren Code liest / unterstützt, wahrscheinlich noch teurer wird, und deshalb ist Einfachheit / Klarheit viel wichtiger.

    
Peter Lawrey 19.10.2010 20:37
quelle