Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Ich habe einen Zeitkritischen Abschnitt (d.h. er muss so schnell wie möglich durchlaufen, weil er seeeeehr oft durchlaufen wird).
Nun die Frage:
ich parse in diesem Abschnitt einen String. Dazu habe ich mir eine Parse-Klasse geschrieben.
Ist es schneller innerhalb dieses Abschnitts für jeden Durchlauf ein neues Objekt dieser Parse-Klasse zu erstellen und damit zu arbeiten oder ist es schneller die Methoden der Klasse statisch zu machen und diese einfach statisch zu benutzen ?
Ich freue mich auf eure Antworten!
Viele Grüße
sladda
Wer sagt denn, dass die Objekterzeuugung überhaupt performancekritisch ist?
Ich könnte meine Hände dafür verwetten, dass der eigentliche Parser viel relevanter ist.
Wer sagt denn, dass die Objekterzeuugung überhaupt performancekritisch ist?
Ich könnte meine Hände dafür verwetten, dass der eigentliche Parser viel relevanter ist.
Sehe ich nicht unbedingt genauso. Kann man gelten lassen wenn man OOP auf Vererbung und Polymorphie beschränkt. In C# gibt es gar statische Klassen, Objekte die so nur einmal existieren können. Was spricht daran gegen OOP? Wir haben einen Zustand mit einem Verhalten gekoppelt und nennen das Objekt (einzig wahre Definition von OOP). Haben auch einen großen Nutzen für die OOP, z.B. Extension Methods zur Erweiterung der Funktionalität existierender Instanzen.
Das ist so falsch, kommt immer auf den Kontext an.
Objekte mit kleinem "Scope" belasten den GC zB. gar nicht.
Sehe ich nicht unbedingt genauso. Kann man gelten lassen wenn man OOP auf Vererbung und Polymorphie beschränkt. In C# gibt es gar statische Klassen, Objekte die so nur einmal existieren können. Was spricht daran gegen OOP? Wir haben einen Zustand mit einem Verhalten gekoppelt und nennen das Objekt (einzig wahre Definition von OOP). Haben auch einen großen Nutzen für die OOP, z.B. Extension Methods zur Erweiterung der Funktionalität existierender Instanzen.
Du musst bedenken dass das hier ein Javaforum ist, kein generelles OO Forum.
In Java gibt es eben enorme Einschränkungen was Vererbung von statischen Methoden betrifft, dazu kommt noch das "shadowing" Problem und natürlich der globale Scope von static Variablen.
Klar kann man dass auch zu einem Pseudo-OOP Konzept ummünzen und "statische Klassen" einführen.. spart man sich dadurch eine getInstance Methode in einem GoF Singleton?
Erweiterung der funktionalität von existierenden Klassen gehen auch ohne statische Methoden, imho sogar sauberer, siehe mixins, allerdings gibt es sowas nicht in Java, dafür in anderen Sprachen die auf der JVM laufen.
Deine "einzig wahre Deifnition von OOP" sehe ich als unzureichend an.
So pauschale Aussagen sind oft gefährlich, weil nicht immer zutreffend.
ice-breaker hatte seine Aussage in Relation zum Rest gesetzt und hat mit dieser Aussage durchaus Recht. Wenn Objekte in einem kleinen Scope im EdenSpace erstellt werden, sind sie auch schnell wieder gelöscht. Dafür braucht es nämlich keinen Full GC.
Klar kann man dass auch zu einem Pseudo-OOP Konzept ummünzen und "statische Klassen" einführen.. spart man sich dadurch eine getInstance Methode in einem GoF Singleton?
Ja die spart man sich. Die braucht es auch nicht und die ist redundant. Baue ich mir eine Util-Klasse mit diversen Routinen, ist eine Singleton Implementierung unnötig. Ich werde nie von dieser Klasse erben, ich werde sie nie instanziieren und ich möchte auch nicht, dass einer je den Design-Fehler begeht und davon erbt. Die Routinen sind statisch und damit performant, die Benutzung so, wie ich es in meinem OOP Programm geplant habe. Meine Domäne freut sich.
Erweiterung der funktionalität von existierenden Klassen gehen auch ohne statische Methoden, imho sogar sauberer, siehe mixins, allerdings gibt es sowas nicht in Java, dafür in anderen Sprachen die auf der JVM laufen.
Deine "einzig wahre Deifnition von OOP" sehe ich als unzureichend an.
Ist meiner Ansicht nach, Data-Hiding miteingeschlossen, für die Wartbarkeit wichtiger als Polymorphie und Vererbung. Die sind natürlich auch wichtig. Aber das war schon weitergedacht. Der Grundgedanke war Zustand gekoppelt an Verhalten zugunsten der Wartbarkeit.
ice-breaker hatte seine Aussage in Relation zum Rest gesetzt und hat mit dieser Aussage durchaus Recht. Wenn Objekte in einem kleinen Scope im EdenSpace erstellt werden, sind sie auch schnell wieder gelöscht. Dafür braucht es nämlich keinen Full GC.
stimmt, eigentlich wollte ich aber darauf hinaus, dass sein Parser wahrscheinlich mehr Performance schluckt als eine Objekterzeuugung und der GC zusammen je benötigen werden, er also dort optimieren soll.
Ja die spart man sich. Die braucht es auch nicht und die ist redundant. Baue ich mir eine Util-Klasse mit diversen Routinen, ist eine Singleton Implementierung unnötig. Ich werde nie von dieser Klasse erben, ich werde sie nie instanziieren und ich möchte auch nicht, dass einer je den Design-Fehler begeht und davon erbt. Die Routinen sind statisch und damit performant, die Benutzung so, wie ich es in meinem OOP Programm geplant habe. Meine Domäne freut sich.
"Die Routinen sind statisch und damit performant" ist reine Mutmassung, sorry.
Solltest das mal versuchen zu messen, ob eine statische Methode schneller ist als eine nicht statische von einem Objekt dass nur ein einziges mal instatiiert wird.
Du wirst rausfinden, dass du das nciht rausfinden kannst
Ausser natürlich in total unrealistischen Anwendungsfällen.
Abgesehen davon halte ich das sog. "Perfomance Argument" für reine Einbildung/Verwirrung, wenn das so wichig würden wir keine abstrakte Highlevelsprachen mit riesigem Overhead verwenden, sondern unsere Programme in Assembler (am besten Opcode) schreiben
Das Problem mit GoF Singletons: Sie vermischen verschiedene Aspekte, SRP wird verletzt, namentlich: Obejkterzeugung und Zugriff, und dann wird man auch noch an eine statische Methode "gekettet".
DI Frameworks lösen diese alten Problem doch sehr gut, ein Spring Singleton zB. ist ein ganz normales POJO ohne spezielle Schnittstelle, es wird eben nur einmal erzeugt.
"Die Routinen sind statisch und damit performant" ist reine Mutmassung, sorry
Solltest das mal versuchen zu messen, ob eine statische Methode schneller ist als eine nicht statische von einem Objekt dass nur ein einziges mal instatiiert wird.
Du wirst rausfinden, dass du das nciht rausfinden kannst
Ausser natürlich in total unrealistischen Anwendungsfällen.
Das Problem mit GoF Singletons: Sie vermischen verschiedene Aspekte, SRP wird verletzt, namentlich: Obejkterzeugung und Zugriff, und dann wird man auch noch an eine statische Methode "gekettet".
DI Frameworks lösen diese alten Problem doch sehr gut, ein Spring Singleton zB. ist ein ganz normales POJO ohne spezielle Schnittstelle, es wird eben nur einmal erzeugt.
Fuer solche Zugriffe bau ich ein generisches Singleton (geht das ueberhaupt in Java?).
Code:
Singleton<SomeClass>.Instance.DoSomething();
DI Frameworks (essentiell Microkernel-Pattern) sind teilweise schwerfaellig in der Konfiguration und dem Deployment. Blanke Object-Builder machen das natuerlich anders, klar, wer das nicht ausnutzt ist selber schuld. Nicht wegen dem Singleton (s.o.), sondern hauptsaechlich wegen Proxies und Interception.
Aber ich moechte eigentlich nur festhalten, dass es voellig legitim und auch im Sinne der OOP ist zu sagen:
Alle Objekte einer Art besitzen gemeinschaftlich ein unveraenderliches Verhalten, dass sie durchfuehren koennen.
Nicht in Java, siehe Spring bzw. Guice, oder gleich die Standards für DI in JEE
Und da sagt noch einer, static sei nicht sehr OOP. Was fuer ein wundervolles Konstrukt! Welch wunderbare Problemloesung. Static ist hoechstens ein bissal vererbungsfeindlich.
Ich behaupte immer noch static ist nicht wirklich OOP, in Java
Zu deinem Link aus Java Sicht: Ist genau das Gegenteil von einem "wundervollen Konstrukt", sondern eine Missgeburt im Sinne des Designs.
Das ist keine Lösung, sondern das ist das Problem.
Wenn man mehr als ein einziges GoF Singleton braucht, hat man etwas falsch gemacht.
Dafür einen isolierten Unittest zu schreiben ist nicht schön, muss schon tricksen bzw. Frameworks nehmen die intern tricksen.
Das ist aber die Java Sicht der Dinge, die nicht unbedingt auf alle OOP Sprachen übertragbar ist, ausser natürlich die OOP Sprachen die gar kein static Konstrukt haben
Zu deinem Link aus Java Sicht: Ist genau das Gegenteil von einem "wundervollen Konstrukt", sondern eine Missgeburt im Sinne des Designs.
Das ist keine Lösung, sondern das ist das Problem.
Gruselig. Aber im Grunde ist das gar kein Singleton, sondern nur ein generischer Wrapper für beliebige Objekte mit einer ziemlich schwerfälligen, Mutex-synchronisierten Lazy-Initialization.
Gruselig. Aber im Grunde ist das gar kein Singleton, sondern nur ein generischer Wrapper für beliebige Objekte mit einer ziemlich schwerfälligen, Mutex-synchronisierten Lazy-Initialization.
Ich brauche genau eine Singleton Implementierung fuer eine Applikation. Da muss sich bei mir nicht zwingenderweise ein Container drum kuemmern. Wenn ich etwas in der Applikation als Singleton haben will, Schnittstelle hin oder her, dann werd ich auch mit Container sicherlich kein Lebenszyklusmanagement spaeter mehr umdefinieren. Letztendlich geht es bei der Singleton-Pattern um Zugriff und der ist wunderbar implementiert (SRP). Der Aufruf ist auch schoen, auch schoener, als ueber einen Container an das Objekt zu kommen und die Vererbungshierachien bleiben sauber. Was will man mehr.
Eine derartige Singleton Implementierung ist einfach nur elegant, wenn man das static-Schluesselwort nicht stiefmuetterlich betrachtet. Es ist eine technisch elegante und extrem simple Loesung, die ohne Container auskommt. Nuechtern betrachtet bietet sie sehr viele Vorteile.
Natuerlich nicht fuer einen Dogmatiker.
In Java koennte man so etwas durchaus auch schreiben, ist halt leider dort ueber Reflection nicht zur Compile-Time pruefbar.
Gruselig. Aber im Grunde ist das gar kein Singleton, sondern nur ein generischer Wrapper für beliebige Objekte mit einer ziemlich schwerfälligen, Mutex-synchronisierten Lazy-Initialization.
Eben nicht, zumindest nicht in Java.
Mock Frameworks sind ja nicht das Problem(schliesslich gibt es ja einige), aber die Auswahl darunter die es schaffen eine statische Referenz umzubiegen ist nicht mehr so groß und diese haben andere Nachteile.
JMock2, meine bevorzugte Mock Lib unterstützt das zB. nicht.
Letztendlich geht es bei der Singleton-Pattern um Zugriff und der ist wunderbar implementiert (SRP).
Beim Singleton Pattern geht es eben nicht um den Zugriff (globale Variable über eine statische Referenz/Methode) sondern um die Tatsache dass es davon nur ein einziges gibt.
Eine derartige Singleton Implementierung ist einfach nur elegant, wenn man das static-Schluesselwort nicht stiefmuetterlich betrachtet. Es ist eine technisch elegante und extrem simple Loesung, die ohne Container auskommt. Nuechtern betrachtet bietet sie sehr viele Vorteile.
Deine Einschätzung von Elegant kann ich nicht teilen und Container & Frameworks sind ja nichts unübliches in Java.
Abgesehen davon hatte ich ja bereits gesagt dass static nütlich ist, aber eben nicht 100% OOP, und genau darum ging es doch?
Diese Singleton-Implementierung ist so einfach testbar wie Klassen mit Injections, da braucht man auch Mock-Framworks etc. pp.
[...]
Letztendlich geht es bei der Singleton-Pattern um Zugriff
Ich kann mich irren, aber möglicherweise gibt es hier ein Verständnisproblem bezgl. Sinn und Zweck eines Singleton. Das GoF-Singleton (also das ursprüngliche Pattern) muss sicherstellen, dass genau ein Objekt der Klasse existiert - sonst geht die Welt unter. Das ist schon eine Einschränkung, die einem das Leben schwer machen kann. Sowas braucht man sehr selten, und vor allem muss man sich Fragen, wieso.
Wenn es dir vordergründig um Zugrifff geht, missbrauchst du das Pattern vielleicht als globale Variable (weil es so schon einfach ist, da ran zu kommen). Falls ich falsch liege, bitte ich um Entschuldigung.
Das Scope "Singleton", wie es manche DI-Frameworks kennen, ist was völlig anderes.
Der Aufruf ist auch schoen, auch schoener, als ueber einen Container an das Objekt zu kommen und die Vererbungshierachien bleiben sauber.
Du kommst nicht über den Container an das Singleton, der Container gibt dir das Singleton. Es ist einfach da, ohne dass man seinen Client-Code an eine bestimmte Implementierung oder statischen Aufruf binden muss. Das ist elegant.
Vielleicht sind wir Java-Leute nur etwas weiter in der Entwicklung? Immerhin kommen viele gute Frameworks aus der Java-Welt - ganz ohne statisch-generische Singleton-Wrapper. Da profitieren auch andere von. Hibernate und Spring gibt es z.B. sogar für dot.net.
EJB, JSF, XML-Hell ...
... um einige der Dinge zu nennen, zu denen eure Ansichten fuehren.
Hm, da seh ich jetzt überhaupt keinen Zusammenhang zum Thema Singleton (zumal das alles völlig überholt ist). Falls das ein Kunstgriff der eristischen Dialektik sein sollte, war das ziemlich plump. Das üben wir noch...
Ich kann mich irren, aber möglicherweise gibt es hier ein Verständnisproblem bezgl. Sinn und Zweck eines Singleton. Das GoF-Singleton (also das ursprüngliche Pattern) muss sicherstellen, dass genau ein Objekt der Klasse existiert - sonst geht die Welt unter.
...missbrauchst du das Pattern vielleicht als globale Variable...
Sehe ich anders, aber ich habe sowieso das Gefühl, dass wir hier Haare spalten.
Du kommst nicht über den Container an das Singleton, der Container gibt dir das Singleton. Es ist einfach da, ohne dass man seinen Client-Code an eine bestimmte Implementierung oder statischen Aufruf binden muss. Das ist elegant.
Aber dafür bindest du dich an eine Konfiguration oder eine Annotation. Ersteres kann zur Compile-Time wieder nicht überprüft werden und führt bei uns in der Firma (größtenteils Java-Schmiede) auch immer wieder zu Problemen, die Stunden kosten.
Vielleicht sind wir Java-Leute nur etwas weiter in der Entwicklung? Immerhin kommen viele gute Frameworks aus der Java-Welt - ganz ohne statisch-generische Singleton-Wrapper. Da profitieren auch andere von. Hibernate und Spring gibt es z.B. sogar für dot.net.
Das ist schon wahr! Die Java-Welt hat auch viel Pionier Arbeit geleistet. Ich mag aber keinen Trampelpfad sondern bevorzuge gepflasterte Straßen. Was kümmern mich aber die tollen Konzepte wenn sie total überzogen umgesetzt werden. Beispielsweise sind EJB und JSF in der Benutzung und Handhabung einfach schmerzhaft. Das wurde jetzt über viele Jahre etwas besser. Derartig designte Frameworks/Technologien findet man in der .NET Welt irgendwie nicht. Im Gegenteil, neuartige Technologien sind meist von Anfang an hervorragend umgesetzt (WPF, LinQ).
Hm, da seh ich jetzt überhaupt keinen Zusammenhang zum Thema Singleton (zumal das alles völlig überholt ist). Falls das ein Kunstgriff der eristischen Dialektik sein sollte, war das ziemlich plump. Das üben wir noch...
Plump ist es, eine elegante Lösung für ein technisches Problem als gruselig abzutun weil es nicht ins Dogma passt.
Die Diskussion war ursprünglich nicht so geplant. Ich gebe ja zu, dass ich etwas pauschalisiert habe. Aber ihr seid das, was Martin Fowler als besessene Objekt-Puristen bezeichnen würde, die sonstige technische Lösungen ablehnen. Da muss ich einfach den Teufels Advokaten spielen.
Da werden 2 Dinge vermischt: Wie oft darf ein Objekt erzeugt werden, und wie greife ich darauf zu.
Typischer Anfängerfehler imho, Globale Variablen nutzen, diese ein Design Pattern nennen und denken die Welt wäre in Ordnung und man hätte eine elegante Lösung *g*
Wenn man das sauber trennt, hat man keinen static zugriff mehr, eben wie ein Singleton in Spring/Guice/CDI.
Aber dafür bindest du dich an eine Konfiguration oder eine Annotation. Ersteres kann zur Compile-Time wieder nicht überprüft werden und führt bei uns in der Firma (größtenteils Java-Schmiede) auch immer wieder zu Problemen, die Stunden kosten.
Plump ist es, mit unzureichendem Verständnis die primitiven Mittel die man hat als "gut/elegant" zu bezeichnen.
Die Diskussion war ursprünglich nicht so geplant. Ich gebe ja zu, dass ich etwas pauschalisiert habe. Aber ihr seid das, was Martin Fowler als besessene Objekt-Puristen bezeichnen würde, die sonstige technische Lösungen ablehnen. Da muss ich einfach den Teufels Advokaten spielen.
Du zeigst doch nur deine Lücken was OOP und Java betrifft, deine Argumentation hat sich von "static ist Objektorientiert" zu "Singleton ist toll" bis zu "OOP ist umständlich" verschoben.
Du bist ein Dogmatiker, der leider sein Fach nicht versteht, sorry.
Wie kann man einerseits auf die GoF Stein und Bein schwören was zB. Singleton betrifft, aber dabei die Grundsätze der OO ignorien, wie SRP?
Man muss alles immer in Frage stellen, und da ist dem SRP ganz klar der Vorzug zu geben zu dem, was die GoF mal in den 90er jahren als Best Practices bzw. "häufig verwendete Muster" zusammengeschrieben hatte.
Vielen Dank maki für die Antwort. Das spart mir eine Menge Zeit. Du hast praktisch alles schon gesagt.
Ich finde es schon bedenklich, hier mitreden zu wollen und dabei den Unterschied zwischen einem GoF-Singleton und einem "DI-Singleton" nicht zu erkennen und das als Haarspalterei abzutun. Das sind zwei völlig verschiedene Dinge!
Sicher kann man die entstandenen Lücken durch erheblichen Mehraufwand abdecken.
Du zeigst doch nur deine Lücken was OOP und Java betrifft, deine Argumentation hat sich von "static ist Objektorientiert" zu "Singleton ist toll" bis zu "OOP ist umständlich" verschoben.
Stimmt doch gar nicht. In wie fern habe ich OOP als umständlich bezeichnet? Es gibt keinen Grund, das Singleton als Pattern abzulehnen und static ist ein probates Mittel in der OOP. Es kommt immer auf den Einsatzzweck an und das ist Objektpurismus nicht unbedingt immer die beste Lösung.
Wenn du das nicht kapierst, dann kann ich dir auch nicht helfen.
Du bist ein Dogmatiker, der leider sein Fach nicht versteht, sorry.
Was für Lücken und was für Mehraufwand?
Entweder man testet und stellt sicher dass der Code funktioniert, oder man arbeitet wie in den 90'er Jahren: Wenn Bugs gefunden werden vom Kunden, fixen wir die.
Stimmt doch gar nicht. In wie fern habe ich OOP als umständlich bezeichnet? Es gibt keinen Grund, das Singleton als Pattern abzulehnen und static ist ein probates Mittel in der OOP. Es kommt immer auf den Einsatzzweck an und das ist Objektpurismus nicht unbedingt immer die beste Lösung.
Ich werd hier nicht weiter mit euch beiden diskutieren. Ich sehe die Dinge teilweise anders und bleibe auch dabei.
Ich glaub, so viele Posts wie du hast, hast du seit den 90ern kein echtes Projekt mehr durchgezogen. Wer soviel schreibt hat doch keine Zeit für Projektarbeit.
Hättest ja gleich zugeben können dass du weder von Java noch von OO Ahnung hast anstatt mit Pseudoargumenten zu versuchen längst wiederlegte Binsenweisheiten als Tatsachen darzustellen.
Ich glaub, so viele Posts wie du hast, hast du seit den 90ern kein echtes Projekt mehr durchgezogen. Wer soviel schreibt hat doch keine Zeit für Projektarbeit.
Uh...Singleton, Static und Objekterzeugung in einem Thread, war klar dass das so ausartet.
Mal ein paar Statements von mir (ja, ich arbeite tatsächlich in dem Bereich, an einer extrem kritischen Anwendung im Finanzbereich).
Objekterzeugung ist teuer
Dieses Märchen hält sich hartnäckig. Das war mit Java < 1.3 mal so. Auch in den EJB 2.x-Zeiten stimmte das teilweise. Deshalb wurden die Objekte auch über einen Pool verwaltet um so wenig wie möglich neu zu erzeugen. Bei EJB lag es aber in keinster weise daran das die Objekterzeung per se teuer war, mehr an dem ganzen Laufzeitkram drum herum.
Das Märchen das Objekterzeugung im "normalen" JSE/JEE-Umfeld teuer ist ist absoluter Quatsch und schlicht falsch.
Singleton
Das Singleton-Pattern wird für alles Mögliche missbraucht, aber meist nicht als das für was es gedacht war. Das Singletonpattern soll sicherstellen das ein Objekt nur einmal existiert. In keinster Weise geht es darum ein Objekt global zur Verfügung zu stellen. Leider habe ich glaub noch nie in irgendeinem Projekt eine richtige Singletonimplementierung gesehen. Dort wurde das Singleton immer als globales Objekt missbraucht.
static or not
Static ist nunmal nicht im Sinne der OOP. Statischer Code ist schwer zu testen und vor allem führt es sehr oft zu Problemen. Beispiel gefällig?
Sobald Preloading am Server ins Spiel kommt gibt es schon Probleme, da die static(-Blöcke) dann sofort durchlaufen werden. Leider ist beim Preloading per Definition noch nicht alles vorhanden. Und schon knallt es und man verbringt Stunden mit der Suche. Nächstes Problem sind z.B. Umfeldern mit verschiedenen Classloadern - auch da ist static != static weil ein statisches Objekt trotzdem in jedem Classloader einmal lebt - was auch zu vielen Problemen führt.
Ich könnte noch zig weitere Beispiele aufführen, aber das ist glaub nicht nötig
Generisches Singleton
Gibt es irgend einen sinnvollen Einsatz dafür? Ich bin froh wenn die Projekte möglichst keine Singletons verwenden und damit biete ich noch einen Weg die Dinger für alles zu mißbrauchen. Der erste Schritt zum Objekt-Pooling.
GC/Compiler können statische Objekte besser aufräumen
Also du unterstellst hier Leuten Unwissenheit und dann kommst du mit so einem Spruch? In Zeiten von Hotspot und Co. hat das null komma null Auswirkungen....und ab dem 1000x (ca.) Aufruf hat sich's eh erledigt..
Zum Thema Optimierung/Performance mal ein schönes Zitat
Der Satz sagt schon alles und ist zu 100% korrekt.
Wenn ich solchen Code hab
Java:
public void runLongTime(){
new A();
new B();
parseOneGigabyteXML();
new C();
new D();
}
dann stellt sich mir doch folgende Frage:
Optimiere ich 4x Objekterzeugung welche effektiv nix kostet oder optimiere ich den Parser der 2GB XML-Dateien parst und dafür gefühlte Stunden benötigt?
Wir gehen mal davon aus das der ganze Vorgang 10 Sekunden läuft. Was hilft es mir wenn ich bei der Objekterzeugung 100ms rausholen kann (wobei 100ms enorm unrealistisch sind bei reiner Objekterzeugung)? Welchen Nutzen hat denn der Kunde davon?
Leute jetzt streitets doch nicht! Es kommt doch aufs Beispiel an oder?
Hab ich vor kurzem gebraucht, wollte mir die Differenz von zwei Images berechnen...
Java:
public static long getDifference(BufferedImage image1, BufferedImage image2) throws Exception {
if(image1.getWidth() != image2.getWidth() || image1.getHeight() != image2.getHeight()){
throw new Exception("bilder nicht gleich groß");
}
long dif = 0;
for(int x = 0 ; x < image1.getWidth(); x++){
for(int y = 0 ; y < image1.getHeight(); y++){
//Variante 1 mit static
int rgb1 = image1.getRGB(x, y);
int rgb2 = image2.getRGB(x, y);
dif +=Math.abs(getRed(rgb1)-getRed(rgb2));
dif +=Math.abs(getGreen(rgb1)-getGreen(rgb2));
dif +=Math.abs(getBlue(rgb1)-getBlue(rgb2));
//Variante 2 mit Color Objekt
Color c1 = new Color( image1.getRGB(x, y));
Color c2 = new Color( image2.getRGB(x, y));
dif +=Math.abs(c1.getRed()-c2.getRed());
dif +=Math.abs(c1.getGreen()-c2.getGreen());
dif +=Math.abs(c1.getBlue()-c2.getBlue());
//Variante 3: Color Objekt wiederverwenden...
//color kann man den rgb wert nicht setzen ;-)
}
}
return dif;
}
public static int getRed(int rgb) {
return (rgb >> 16) & 0xFF;
}
public static int getGreen(int rgb) {
return (rgb >> 8) & 0xFF;
}
public static int getBlue(int rgb) {
return (rgb >> 0) & 0xFF;
}
Was ist schneller bei einem 2 Mega Pixel Bild?
Wir haben hier 4 Mio Color Objekt Instanzierungen dir wir uns sparen können!
Ich weiß das eine gängige Meinung ist, dass man nicht optimieren soll. Aber es gibt Ausnahmen!!!
Wäre dein Beispiel nicht mit einer statischen Methode, bräuchtest du auch getRed etc. Methoden nicht statisch, du hättest dann ein Objekt welches diese Werte auch nur ein einziges mal erzeugen würde, müsstest halt nur dafür sorgen dass dieses Obejkt wiederverwendet würde
Der vollständikeit halber sei das Flyweight APttern noch erwähnt, geht in genau die gleiche Richtung.
Die Methode die du da zeigst ist auch prinizipiell einfach zu testen mit einem isolierten Unittest, weil sie eben keinen "kontext" hat, also keine (statischen/instanz) Variablen.