Kundenrezension

9 von 20 Kunden fanden die folgende Rezension hilfreich
2.0 von 5 Sternen Eine effektive Anleitung für möglichst ineffizienten Kode., 26. April 2014
Rezension bezieht sich auf: Effective Java: A Programming Language Guide (Java Series) (Taschenbuch)
In vielen Java Programmen machen die Nutzdaten nur einen Bruchteil des allokierten Heaps aus [1]. Bei kurzen Strings wie sie z.B. in Personen- oder Städteverzeichnissen vorkommen, ist der interne Header viel größer als die eigentliche Information. Dasselbe gilt bei kleinen Objekten. Der Object-Header ist typischer Weise 16-Byte. Noch übler wird es, wenn diese kleinen Objekte/Strings in Collections gespeichert werden. Eine besonders aufgeblähte Datenstruktur sind die allseits beliebten Hashmaps und Hashsets [2]. Beim Boxing einer Integer hat man 80% bürokratischen Overhead und 20% Nutzdaten. Derselbe Effekt tritt bei Enums auf. Eine Enum ist kein Integer wert, sondern eine Klasse und man schleppt damit den Klassen-Overhead mit herum. In der Regeln werden sie aber nur als symbolische Konstanten vulgo Integers verwendet.

Dieses Buch ist eine systematische Anleitung wie man im Namen von Effektiver Programmierung Daten möglichst gross aufbläst und das Programm möglich abstrakt-kompliziert macht. All die oben aufgezählten "Memory-Bloats" werden als die alleinseligmachende Art der Javaprogrammierung präsentiert. Wobei nicht klar ist, was der Autor unter "Effektiv" versteht. Mit Sicherheit nicht effizienter Kode.

Das Standardargument für diesen Ressourcenwucher ist: Was kostet schon ein Giga Memory oder gar Plattenplatz gegen einen Programmierer. Effizientes Programmieren bedeutet jedoch nicht automatisch geringere Produktivität oder mehr Bugs. Ganz im Gegenteil, es setzt vorraus, dass man das Problem gründlich versteht und dass man sein Fach von Grund auf beherrscht. Wer seine Datenstrukturen ohne viel Nachzudenken was intern geschieht in eine Java-Collection wirft, wer niemals gemessen hat, wie lange Methode A braucht und ob nicht Methode B schneller ist, wird niemals ein richtiger Programmierer werden. Wahrscheinlich wird er niemals irgendetwas richtig können, weil ihm der Sinn für die gründliche Auseinandersetzung mit einem Gegenstand fehlt.

Tatsächlich wachsen die Anforderungen mindestens genauso schnell wie die Hardware. Jedes ernsthafte Programm stößt über kurz oder lang an Performance und Ressourcen Grenzen. Z.B. haben wir einen Finance-Server gebaut. Ursprünglich für ein paar hundert verschiedene Assets und tägliche Daten. Inzwischen sind es ein paar Tausend mit High-Frequency Zeitreihen. Der Server erreichte damit in der ursprünglichen Konzeption die Grenzen des Wachstums. Ich habe mich daher in den letzten Wochen intensiv mit effizienten Java-Strukturen beschäftigt. Die neue Version ist 5-100 x so schnell und verbrät nur einen Bruchteil von Plattenplatz und Memory. Das geht natürlich nicht mit kleinen kosmetischen Veränderungen. Es musste z.B. auch die MySQL-Datenbank daran glauben. Es wurden aber auch handgeschnitzte und effektive Datenstrukturen für Zeitreihen entwickelt. Ein Element einer Zeitreihe besteht typischer Weise aus einem Zeitstempel (int oder long) und einem Wert (double). Es ist höchst uneffektiv für jedes Element ein Objekt zu erzeugen und dieses z.B. in einer ArrayList der Reihe nach zu speichern (komplexerere Container sind noch übler). Stattdessen speichert man die Zeitstempel in eine Integer- und den Wert in eine Double-Array. Nachdem man die Frequenz der Daten und den Zeitbereich kennt, kann man die Größe der Array von vornherein sehr gut abschätzen. Man benötigt keine dynamischen Strukturen. Dieses Design ist gegen alle in diesem Buch gepredigten Regeln. Es ist jedoch einfach, schnell und auch nicht fehleranfälliger wie all die Regeln der schönen neuen Programmierwelt. Es ist nur weniger allgemein. Es braucht aber auch nicht allgemeiner sein. Und falls die Datenstruktur sich einst doch als zu starr erweist, schreibt man sich halt eine neue TimeseriesExtended Klasse. Von vornherein alle möglichen und unmöglichen Erweiterungen in Datenstrukturen einzubauen gehört laut [2] zu den 12 Patterns vulgo Ursünden für aufgeblähten Kode. Man muss Kode sowieso von Zeit von Zeit wegschmeissen und gänzlich neu schreiben.

Man kann auch den in C++ geschrieben Kode von H. Press et. al.: Numerical Recipes 3rd Ed. hernehmen. Der Kode verstößt massiv gegen die Regeln der C++ "Effective-Gurus". Er löst aber auf sehr effiziente Weise das jeweilige Problem, dass er lösen soll.

Meiner Meinung nach sind Bloch, Myers et. al. Sektenprediger die dem staunenden Publikum Snake-Oil verkaufen. Man sollte stattdessen Bücher von ernsthaften Leuten die D. Knut, H. Press oder D. Comer lesen.
Auch das gute alte "Writing Efficient Programs" von J. Bentley ist es wert immer wieder einmal gelesen zu werden. Die Beispiele mögen teilweise veraltert sein, der Geist, die Einstellung, die es ausstrahlt, jedoch nicht. Es ist die Antithese zu einer allgemeinen Einstellung die vollkommen unverantwortlich mit Ressourcen - sei es nun Lebensmittel, Energie oder Memory - umgeht.

[1]: N. Mitchell, Sevitsky G.: The Causes of Bloat, The Limits of Health.
[2]: Chis A., Mitchell N., Schonberg E. et al.: Patterns of Memory Inefficiency.
Helfen Sie anderen Kunden bei der Suche nach den hilfreichsten Rezensionen 
War diese Rezension für Sie hilfreich? Ja Nein

[Kommentar hinzufügen]
Kommentar posten
Verwenden Sie zum Einfügen eines Produktlinks dieses Format: [[ASIN:ASIN Produkt-Name]] (Was ist das?)
Amazon wird diesen Namen mit allen Ihren Beiträgen, einschließlich Rezensionen und Diskussion-Postings, anzeigen. (Weitere Informationen)
Name:
Badge:
Dieses Abzeichen wird Ihnen zugeordnet und erscheint zusammen mit Ihrem Namen.
There was an error. Please try again.
">Hier finden Sie die kompletten Richtlinien.

Offizieller Kommentar

Als Vertreter dieses Produkt können Sie einen offiziellen Kommentar zu dieser Rezension veröffentlichen. Er wird unmittelbar unterhalb der Rezension angezeigt, wo immer diese angezeigt wird.   Weitere Informationen
Der folgende Name und das Abzeichen werden mit diesem Kommentar angezeigt:
Nach dem Anklicken der Schaltfläche "Übermitteln" werden Sie aufgefordert, Ihren öffentlichen Namen zu erstellen, der mit allen Ihren Beiträgen angezeigt wird.

Ist dies Ihr Produkt?

Wenn Sie der Autor, Künstler, Hersteller oder ein offizieller Vertreter dieses Produktes sind, können Sie einen offiziellen Kommentar zu dieser Rezension veröffentlichen. Er wird unmittelbar unterhalb der Rezension angezeigt, wo immer diese angezeigt wird.  Weitere Informationen
Ansonsten können Sie immer noch einen regulären Kommentar zu dieser Rezension veröffentlichen.

Ist dies Ihr Produkt?

Wenn Sie der Autor, Künstler, Hersteller oder ein offizieller Vertreter dieses Produktes sind, können Sie einen offiziellen Kommentar zu dieser Rezension veröffentlichen. Er wird unmittelbar unterhalb der Rezension angezeigt, wo immer diese angezeigt wird.   Weitere Informationen
 
Timeout des Systems

Wir waren konnten nicht überprüfen, ob Sie ein Repräsentant des Produkts sind. Bitte versuchen Sie es später erneut, oder versuchen Sie es jetzt erneut. Ansonsten können Sie einen regulären Kommentar veröffentlichen.

Da Sie zuvor einen offiziellen Kommentar veröffentlicht haben, wird dieser Kommentar im nachstehenden Kommentarbereich angezeigt. Sie haben auch die Möglichkeit, Ihren offiziellen Kommentar zu bearbeiten.   Weitere Informationen
Die maximale Anzahl offizieller Kommentare wurde veröffentlicht. Dieser Kommentar wird im nachstehenden Kommentarbereich angezeigt.   Weitere Informationen
Eingabe des Log-ins
 

Kommentare

Von 1 Kunden verfolgt

Sortieren: Ältester zuerst | Neuester zuerst
1-4 von 4 Diskussionsbeiträgen
Ersteintrag: 15.11.2014 12:40:04 GMT+01:00
Alex meint:
Meiner Erfahrung nach ist der Preisaufschlag einer ArrayList gegenüber einem Array vernachlässigbar. Es sei denn man füllt diese mit primitiven Datentypen. Aber für primitive Datentypen gibt es eigene Collection Libraries, falls man denn das letzte Bisschen Effizienz rausholen möchte. Speicher- und Laufzeiteffizienz sind wichtig, aber erst wenn sie gebraucht werden. Die Bottlenecks sind meistens Netzwerk- oder Datenbankanbindung. Es würde gar nichts bringen den Code 100x effizienter zu machen, wenn er dann 99% der Zeit auf eine extrne API wartet. In erster Linie sollte der Code nicht anfällig für Fehler, gut lesbar und wartbar sein. Selbstverständlich gibt es Fälle, wie der von Ihnen beschriebene, in denen man Codequalität und Lesbarkeit der Effizienz opfert. Sie sind aber eher die Ausnahme.

Veröffentlicht am 18.11.2014 16:54:43 GMT+01:00
makr meint:
Java ist eine Sprache, die für völlig andere Zwecke als starke lineare Performanceoptimierung konzipiert ist. Man soll damit auch nicht Assembler und Datenbanken ersetzen.
Wenn Collections mehrere GB groß sind, ist das in aller Regel ein architektonisches Problem, das durch Object Stores oder Datenbanken gelöst werden sollte, nicht durch Optimierung des Speicherverbrauchs dieser Datentypen.

Im Unternehmenskontext spielen Time to Market, Implementierungskosten, Wartbarkeit und Staffing eine viel größere Rolle als gesteigerte Hardwareanforderungen durch lineare Performanceverluste. Modularisierung durch Abstraktion statt Implementierungen über Interfaces. Bei nicht-performancekritischen KOmponenten interessiert es doch niemanden, wie genial optimiert etwas umgesetzt wurde, wenn man sich dafür ewig einarbeiten muss, um zu verstehen, wie eine fachliche Anforderung technisch umgesetzt wird. Stellen sich Komponenten als nicht-performant genug heraus, müssen sie halt neu entwickelt werden.
Wenn, dann scheitern Java-Projekte eigentlich immer an der Architektur, nie an der Implementierung.

Veröffentlicht am 21.11.2014 09:28:01 GMT+01:00
Mimir meint:
Der Autor betont, Hilfestellungen geben zu wollen, „so that you can write code that is clearer, more correct, more robust, and more reusable“. Genau das tut er mit seinem Werk in meinen Augen. Nach der Lektüre „Ihrer Kritiken“ (vulgo Unterstellungen) am Buch von Bloch habe ich dessen Abhandlungen auf dem Hintergrund Ihrer Ausführungen quer gelesen. So fielen mir folgende ausgewählte Punkte auf, die sich auf (aus dem Zusammenhang gerissene) Ausführungen Ihrerseits beziehen:

1. Eine Enum ist kein Integer wert, sondern eine Klasse und man schleppt damit den Klassen-Overhead mit herum. In der Regeln werden sie aber nur als symbolische Konstanten vulgo Integers verwendet.
Welche Regeln meinen Sie, auf welchen Statistiken beruhen Ihre Aussagen? Oder sind das alles nur private, verallgemeinerte Erfahrungen oder Einschätzungen? Bloch empfiehlt die sinnvolle Verwendung von Enums auf Seite 150: „It is easy to write a rich enum type … . To associate data with enum constants, declare instance fields and write a constructor that takes the data and stores it in the fields“.
Eine symbolische Konstante als Integer zu verwenden, also wiederum ein Objekt, ist wirklich wenig praktikabel. Das zeigt Bloch mit seinem Item 49 „Prefer primitive types to boxed primitives“ und betont es in Item 55: “Optimize judiciously” erneut. Oder war ihre Aussage nur schlampig formuliert und Sie meinten int statt Integer?

2. All die oben aufgezählten "Memory-Bloats" werden als die alleinseligmachende Art der Javaprogrammierung präsentiert. Wobei nicht klar ist, was der Autor unter "Effektiv" versteht. Mit Sicherheit nicht effizienter Kode.
Ich konnte die von Ihnen propagierte „alleinseligmachende Art der Javaprogrammierung“ im Buch nirgends entdecken. Den Unterschied zwischen Effektivität und Effizienz lernen Informatikstudenten bereits im ersten Semester; was wollen Sie also mit dieser (rhetorischen?) Aussage ausdrücken? Nur effizienter Code ist guter Code? Zu welchen immensen Problemen effizienter Code führen kann hat uns allen das Jahr2000-Problem eindrucksvoll gezeigt.

3. Es ist höchst uneffektiv für jedes Element ein Objekt zu erzeugen und dieses z.B. in einer ArrayList der Reihe nach zu speichern (komplexerere Container sind noch übler). Stattdessen speichert man die Zeitstempel in eine Integer- und den Wert in eine Double-Array.
Genau auf die ineffektive Verwendung von Objekten statt Primitiven weist Bloch in „CHAPTER 2 CREATING AND DESTROYING OBJECTS“ mit „Item 5: Avoid creating unnecessary objects“ auf Seite 20ff hin. Ebenso auf den Fehler, den Sie hier propagieren, nämlich Integer und Double statt int und double zu verwenden; Speicher- und Zeitineffizienz wären die logische Konsequenz.

4. Es ist jedoch einfach, schnell und auch nicht fehleranfälliger wie all die Regeln der schönen neuen Programmierwelt.
Es verwundert mich nun doch, dass Sie als Mathematiker den Vergleichspartikel falsch verwenden. Was das von Ihnen beschriebene, sehr simple Beispiel mit den von Bloch benannten Punkten in seinem Buch zu tun hat, erschließt sich mir überhaupt nicht.

5. Man muss Kode sowieso von Zeit von Zeit wegschmeissen und gänzlich neu schreiben.
Diese Herangehensweise halte ich für ausgesprochen gefährlich und wenig qualitätsbewusst. Das mag im akademischen Bereich üblich sein oder bei der Erstellung von Prototypen; hat aber nichts mit notwendigem und teilweise unumgänglichem Refactoring zu tun. Code sollte, und damit zitiere ich Bloch noch einmal, u.a. korrekt, lesbar, robust und erweiterbar, also wartbar sein. Keine kostenbewusste Firma wird Geld dafür ausgeben, vorhandenen Code neu zu erstellen, weil er zwar optimiert und effizient, aber nicht änderbar ist.
Der unverantwortliche Umgang mit Ressourcen jeglicher Art ist anzuprangern, da stimme ich Ihnen vollumfänglich zu. Dazu gehört auch der verschwenderische Umgang mit den Ergebnissen intellektueller Arbeit, seien es Programme oder ein literarisches Werk.

Nach der zugegebenermaßen oberflächlichen Durcharbeitung des Buches kann ich nur feststellen: Sie erscheinen mir hier wie ein Politiker, der anderen etwas unterstellt, was diese nicht gesagt haben, und das dann genüsslich zerpflückt. Auf der anderen Seite ist die reduktionistische Sicht auf Effizienz in meinen Augen ein Rückschritt in das letzte Jahrhundert, als die so genannte Softwarekrise ihre weiten Kreise zog. Bloch macht Vorschläge, wie die vorhandenen Sprachkonstrukte von Java sinnvoll eingesetzt, Fallstricke umgangen und Probleme besser gelöst werden können – jede/r kann die Punkte, die ihm zusagen, annehmen und über die anderen zumindest nachdenken. Ich kann einigen Ihrer Ausführungen prinzipiell zustimmen, doch haben diese insgesamt sehr wenig mit dem Inhalt und der Intention des besprochenen Buches zu tun.

Veröffentlicht am 03.12.2014 05:58:34 GMT+01:00
David E. meint:
Um nicht von den sehr guten Anmerkungen meiner Vorredner abzulenken: Effektivität und Effizienz sind zwei grundverschiedene Dinge. Sie schließen sich nicht aus, aber die Aussage, dass "jedes Programm früher oder später an Performance oder Ressource-Grenzen" stößt ist total Quatsch.
‹ Zurück 1 Weiter ›

Details

Artikel

4.7 von 5 Sternen (22 Kundenrezensionen)
5 Sterne:
 (19)
4 Sterne:
 (1)
3 Sterne:
 (1)
2 Sterne:
 (1)
1 Sterne:    (0)
 
 
 
EUR 52,61 EUR 35,92
In den Einkaufswagen Auf meinen Wunschzettel
Rezensentin / Rezensent


Ort: Altmelon, Waldviertel

Top-Rezensenten Rang: 1.147