2012-06-03 4 views
5

Ich arbeite an einer Android-App und eine Methode, die ich schreibe, könnte eine Reihe von Mal aufgerufen werden. Bei dieser Methode aktualisiere ich die Benutzeroberfläche. Speicherverbrauch und Leistung sind mir wichtig. So wie ich es sehe, habe ich zwei Möglichkeiten, die Benutzeroberfläche zu ändern.Java: Speichern globale Variablen Speicher und/oder Zeit?

Die erste ist, zu jeder Zeit neue Objekte macht. Das ist etwas zu sagen wie:

public void myMethod(){ 
new View().makeVisible(); 
} 

Das zweite ist das Objekt als eine Variable global und verweisen sie in dem Verfahren zu erklären. Das könnte so aussehen:

View myView = new View(); 

public void myMethod(){ 
myView.makeVisible(); 
} 

Offensichtlich wird die Methode, wenn diese Methode nur ein paar Mal aufgerufen wird, klein sein. Aber wenn ich das viele Male anrufe, und da viele Variablen auf diese Weise aufgerufen/erstellt werden, erhöht der zweite Weg die Leistung?

+0

Möchten Sie die Instanzen erneut verwenden? – SLaks

+0

Ich kann, aber ich habe auch nicht – Flynn

+1

Jede Zeit/Speicherplatz Einsparungen sind um ein 10x Kosten zu Gesundheit übertroffen. –

Antwort

2

Wie die anderen Antworten haben angegeben, stattdessen das gleiche Objekt Wiederverwendung wiederholt zur Herstellung eines neuen für jeden Methodenaufruf Instanziierung wird der Speicherplatzbedarf und die Leistung zu verbessern in Bezug auf die Garbage Collection reduzieren.

Aber ich würde eigentlich zuerst über Wartbarkeit denken. Wird das gleiche Objekt wiederverwendet, wodurch Ihr Code viel komplizierter wird (und möglicherweise Bugs einführt)? Es ist gut, beim Programmieren die Effizienz im Auge zu behalten, aber eine vorzeitige Optimierung zu vermeiden, die Ihr Projekt erschwert und die Entwicklung verlangsamt.

Wenn die Leistung und Speichernutzung ein Anliegen sind, dann ja, es profitieren Sie die gleiche View wiederzuverwenden:

final View myView = new View(); //made final because it shouldn't be reassigned 

Wenn Sie wirklich bekommen Ressource gesinnten möchten, können Sie auch die lazy-laden Objekt - das heißt, erstellen Sie es nur, sobald es benötigt wird.Allerdings würde ich Suppliers.memoize(Supplier) kümmern diese anstelle von Hand-Codierung, dass das Verhalten unter Verwendung von Guava des empfehlen:

final Supplier<View> myViewSupplier = Suppliers.memoize(new Supplier<View>() { 
    @Override 
    public View get() { 
     return new View(); 
    } 
}); 

... 

public void myMethod() { 
    View myView = myViewSupplier.get(); //lazy-loads when first called 
    myView.makeVisible(); 
} 

die wahrscheinlich obwohl für diese besondere Situation extrem ist.

0

Die globale Variable ist effizienter.

Erstellen neue Objekte haben mehr von einem Speicherbedarf, weil jedes Mal, wenn die Sicht erstellt wird und die alte Ansicht ersetzt, hat die alten Müll gesammelt werden. Wenn Sie dieselbe Ansicht mit einer globalen Variablen wiederverwenden, erhält das System die Aufgabe, ein neues Objekt zu erstellen und das alte Objekt zu sammeln.

Edit: Die globale Variable ist nur eine Referenz auf das Objekt, nicht das Objekt selbst.

0

Nun, wenn Sie jeden Konstruktor eine neue Instanz erstellen, im Wesentlichen Sie ausführen Arbeit wieder ist, dass nicht unbedingt erforderlich. Wenn ich in Ihren Schuhen wäre, hätte ich die globale Variable Option, dann löschen Sie die Ansicht und neuzeichnen auf dem gleichen Objekt, wenn überhaupt möglich. Dies verhindert die Möglichkeit einer wiederholten Speicherfreigabe und Zuweisung mit der anderen Methode. Wenn Sie also davon ausgehen, dass das Clearing besonders teuer ist - genug, um es zu empfehlen, ständig neue Ansichten zuzuweisen, dann löschen Sie es. Ein weiterer Anreiz zur Wiederverwendung des gleichen Objekts besteht darin, dass Java Virtual Machine-Implementierungen sich bei der Verwendung von Garbage Collection dadurch unterscheiden, dass eine Variable nicht mehr in den Geltungsbereich fällt, wenn der der JVM zugeordnete Speicher freigegeben ist nicht immer gleich. Sie können feststellen, dass mit der Alternative, Sie haben Fälle, in denen viele Ansichten sequenziell zugeordnet sind, aber nicht alle freigegeben, bis der Prozess für eine Weile im Leerlauf ist, effektiv machen die App ein Speicher Schwein genau wie Sie nicht wollen.

1

Ich denke nicht, dass die Entscheidung rein auf Effizienz basieren sollte - stattdessen auf welcher Zusammensetzung die Domäne, die Sie zu modellieren versuchen, besser darstellt. Die Frage, die gestellt werden muss, lautet: "Welches ist die richtige Struktur für meine Klasse, die View verwendet?".

Die Verwendung einer Instanzvariable ist nicht global - sie ist im Kontext des deklarierenden Objekts enthalten. Globals sollen nicht in OO existieren, obwohl öffentliche statische Variablen ziemlich nahe kommen.

Die erste Entscheidung ist, wo Ihre "View" -Instanz logisch zur Absicht der Klasse/Methode gehört, die sie verwendet. Wenn die Klasse, die es verwendet, eine Fabrik irgendeiner Art ist und "myMethod" eine Fabrikmethode ist, dann gebe ja eine neue Instanz zurück.

Wenn "View" ein logisches Feld Ihrer Klasse ist und irgendwie dabei hilft, seinen Zustand und sein Verhalten zu erfassen und zu verbessern, gibt es keinen Grund, jedes Mal ein neues zu erstellen. Behalte einfach seinen Zustand bei und arbeite mit dem vorhandenen Objekt.

Aus Ihrer Beschreibung scheint es, als ob Sie versuchen, den Zustand einer Ansicht zu erhalten und zu aktualisieren. Es ist sinnvoll, es in den gewünschten Zustand zu ändern und es erneut anzuzeigen, anstatt jedes Mal ein neues Objekt zu erstellen. Da es funktional scheint, dass beide Ansätze in Ihrem Szenario funktionieren, würde ich die zweite Alternative wählen und vermeiden, unnötige Objekte zu erstellen.