Codequalitaet

Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hallo anhand dieses Beispiel eine kleine Frage zum Thema Codequalitaet

Code:
public static double Wertemin (double z[]) {      
    int min = 0; 
    for (int i = 1; i < z.length; i++) { 
        if (z[i] < z[min])  { 
             min = i; 
        } 
    } 
    return z[min]; 
}

Code:
private static boolean isNotMin(Double currentMin,Double number) {
    return currentMin == null || currentMin > number;
}

public static Double min( double numbers[] )
  {
    Double result = null;
    for( double number : numbers )
    {
      if(isNotMin(result,number))
      {
        result = number;
      }
      else
      {
        // nothing to do
      }
    }
    return result;
}

Welcher dieser beiden Versionen ist verstaendlicher ? besser ? sinnvoller ? etc....

oder anders ausgedrueckt welche wuerdet Ihr empfehlen...

ps: Das in der ersten Version bei einem leeren Array eine Exception entsteht ist nicht relevant...
 
S

SlaterB

Gast
die erste, was in 10 Zeilen zu behandeln ist wird durch Pseudo-Objektorientierung nur schlimmer

aber Operationen klein schreiben!

und längere Variablennamen + Kommentare schaden in Version 1 auch nicht,
die schickere for-Schleife + Hilfsvariable für min auch nicht, warum die Anzahl der Arrayzugriffe ohne Not verdoppeln?
 
G

Gast (Version2)

Gast
wird durch Pseudo-Objektorientierung nur schlimmer

Jede "Bedingung" sollte in eine eigene Methode ausgelagert werden. Dies ermoeglicht die fachliche Benennung der Bedingung (in diesem Fall isNotMin) und ermoeglicht so, dass der Leser NICHT zuerst die Bedingung verstehen muss, sondern sofort sieht welche Bedeutung sie hat.

Dies koennte zwar auch durch einen Kommentar erfolgen. Allerdings stoeren Kommentare im Normalfall den Lesefluss und machen den Kode unübersichtlicher.

Ist diese Begreundung sinnvoll ?
 
S

SlaterB

Gast
was heißt schon sinnvoll..,
es ist eine Art der Programmierung, die ein bestimmtes Konzept konsequent verfolgt, ja,

aber ich persönlich habe a) sowas noch nie gesehen, würde b) beim Lesen verrückt werden und glaube c) dass man damit bei größeren Sachen als solchen Mini-Programmen untergeht
:bae:
 
G

Guest

Gast
Gast (Version2) hat gesagt.:
Jede "Bedingung" sollte in eine eigene Methode ausgelagert werden

jede? wer sagt das? isNotMin? pff was heißt das? ist nicht minimum? welcher parameter, der erste oder zweite?
ich find a<b verständlicher! man sell es mit der modularisierung auch nicht übertreiben.

ein (a<b&&c==a)||x>3 würde sinn machen, aber in diesem fall find ich auch die erste variante besser.
 

Marede

Mitglied
In Sachen Codequalität kann man sich auch immer gerne das Checkstyle-Plugin für Eclipse anschauen. Hier findet man eine automatisierte Unterstützung schon während der Code-Eingabe, die darüber hinaus auch noch persönlich angepasst werden kann.
 
B

Beni

Gast
Ich möchte hier auch ein Performanceargument einbringen:
Die zweite Version benötigt n neue Objekte, und macht n zusätzliche Methodenaufrufe. Das benötigt einiges an Zeit.

("No premature optimization" hat schon seine Berechtigung, aber wenn man zwei ähnlich übersichtliche Varianten hat, gibt es keinen Grund die langsamere zu wählen.)

Zu
Jede "Bedingung" sollte in eine eigene Methode ausgelagert werden. Dies ermoeglicht die fachliche Benennung der Bedingung (in diesem Fall isNotMin) und ermoeglicht so, dass der Leser NICHT zuerst die Bedingung verstehen muss, sondern sofort sieht welche Bedeutung sie hat.
Man kanne es auch übertreiben... wer Probleme hat ein "<" zu verstehen, dem hilft auch eine zusätzliche Methode nicht :wink:
 
M

maki

Gast
Warum denn nicht sortieren?
Code:
public static Double min(double numbers[]) {
		
    Arrays.sort(numbers);
		
    return numbers[0];
}
 

Marco13

Top Contributor
Jede "Bedingung" sollte in eine eigene Methode ausgelagert werden.

Jo, aber dan bitte konsequent. Also nicht
Code:
private static boolean isNotMin(Double currentMin,Double number) {
    return currentMin == null || currentMin > number;
}
sondern
Code:
private static boolean isNotMin(Double currentMin,Double number) 
{
    return or(isNull(currentMin), isLarger(currentMin, number))
} 

private static boolean or(boolean a, boolean b) 
{
    return a || b;
} 
private static boolean isNull(Object x) 
{
    return x == null;
} 
private static boolean isLarger(Double a, Double b) 
{
    return a > b;
}

Mal im ernst: Wenn ich die zweite Version sehen würde, würde ich sie dem Autoren um die Ohren hauen. Überflüsigen Methode, Ineffizent, Umständlich, und sowas wie
Code:
      else
      {
        // nothing to do
      }
ist ja mal mega- :autsch:


@maki: Sortieren dauert im Worst case O(n^2), die Minimumsuche aber nur O(n).
 

Saxony

Top Contributor
Marco13 hat gesagt.:
@maki: Sortieren dauert im Worst case O(n^2), die Minimumsuche aber nur O(n).

Hiho,

hier mal mein Senf dazu.

Wenn häufig gesucht werden muss, aber das Feld sich selten ändert, so ist es doch besser dieses jedes Mal zu sortieren bei Änderungen.

Sortierung: Worst Case O(n²), Best Case O(n*log(n))

Danach dauert eine Suche nur noch im Mittel: O(log*log(n)) ujnd im schlechtesten Fall: O(log(n))

Zur Sortierung eignet sich ein Quicksort, bei großen Feldern ist ein Mix aus Quick- und Insertionsort die beste Wahl.

[edit]
Aso falls jetzt einer fragt ab wann ein Feld groß ist, oder noch besser, was die beste Wahl des Pivotelementes bei Quicksort ist, den verweise ich auf eine schier unüberschaubare Menge manifestartiger Literatur zu diesen Themen.
[/edit]

bye Saxony
 
L

lhe

Gast
Der leere Else - Case ist gar nicht so ungewöhnlich.
Ich habe auch mal für eine Firma gearbeitet, die genau das in den Coding Conventions vorgeschrieben hat.
Den Sinn habe ich nicht wirklich verstanden, jedoch sagte man mir, daß dies beweisen würde, daß der Programmierer
sich Gedanken um einen evtl. Else - Case gemachte hätte :)

Ansonsten würde ich gefühlsmäßig auch Variante a bevorzugen, denn man muß einfach nicht jeden Mist
modularisieren. Dabei kommt in großen Projekten nur unverständlicher Murcks raus und der Programmierer, der
das mal debuggen darf, wird zum Code-Hopper :D

Gruß
lhe
 
M

maki

Gast
@maki: Sortieren dauert im Worst case O(n^2), die Minimumsuche aber nur O(n).
Solange die Performance nicht nachprüfbar ein Problem darstellt, hat man sie gefälligst zu ignorieren und den einfachsten Code zu schreiben der möglich ist.

Frühzeitige Optimierung ist die Wurzel allen übels.
 
S

SlaterB

Gast
wieso dauert Sortieren im Worst-Case n^2?
ist Quicksort nicht garantiert n log n oder habe ich bei den zahllosen Abhandlungen über sowas elementares wie die x bekannten Sortieralgorithmen nicht richtig aufgepasst?

@maki: nene, das ist ein abgeschlossenes Gebiet, was für sich mit minimalen Aufwand extrem optimiert werden kann ohne jeden Aufwand oder Nachteil für andere Gebiete, in diesem Fall spricht nie etwas gegen optimieren,
 

tfa

Top Contributor
SlaterB hat gesagt.:
wieso dauert Sortieren im Worst-Case n^2?
ist Quicksort nicht garantiert n log n oder habe ich bei den zahllosen Abhandlungen über sowas elementares wie die x bekannten Sortieralgorithmen nicht richtig aufgepasst?

Nein, wenn bei Quicksort das Pivot-Element wiederholt unglücklich gewählt wird, entartet der Algorithmus zu O(n²).
Es gibt aber Verfahren, die garantiert O(n*log n) sind, z.B. das in Array.sort(Object[]) verwendete Insertion-Sort.
 
S

SlaterB

Gast
also Worst-Case im Sinne von theoretischen Zufall und nicht von z.b. umgekehrter Sortierung?
 

tfa

Top Contributor
Das ist alles abhängig von der Wahl des Pivot-Elements. Wenn Du z.B. immer das erste Element auswählst, dauert eine sortierte Liste O(n²). Am besten man nimmt ein Element aus der Mitte oder ein zufälliges.
 
G

Gast(Version2)

Gast
Beispiel:

Der leere Else - Case ist gar nicht so ungewöhnlich.
Ich habe auch mal für eine Firma gearbeitet, die genau das in den Coding Conventions vorgeschrieben hat.
Den Sinn habe ich nicht wirklich verstanden, jedoch sagte man mir, daß dies beweisen würde, daß der Programmierer
sich Gedanken um einen evtl. Else - Case gemachte hätte

Dies ist eine Begruendung fuehr die leere Else Bedingung!

Fehlende Else Bedinungen sind eine sehr haeufige Fehlerquelle. Untersuchung aus dem Jahr 1978 (zugegeben sehr alt aber eindrucksvoll):

17 Prozent der ifs hatte einen else Zweig. Aber 50 bis 80 Prozent haetten fachlich einen else Zweig aufweisen muessen...

Deswegen die Verpflichtung sich ueber den else Zweig Gedanken zu machen und dies auch im Kode zu dokumentieren durchaus berechtigt.

Also wer Argumente gegen diese Begruendung bei steuern kann; Gerne... Aber bitte nicht das ist mega scheisse oder ist nicht performant. Performance ist immer ein Totschlagargument, denn dann sollte man gleich Assembler programmieren ist ja schliesslich deutlich performanter als Java....

denn man muß einfach nicht jeden Mist modularisieren.

Wieso nicht ? Wenn die Modularisierung zum Verstaendnis des Code beitraegt ?


Code:
private static boolean isNotMin(Double currentMin,Double number) 
{ 
    return or(isNull(currentMin), isLarger(currentMin, number)) 
} 

private static boolean or(boolean a, boolean b) 
{ 
    return a || b; 
} 
private static boolean isNull(Object x) 
{ 
    return x == null; 
} 
private static boolean isLarger(Double a, Double b) 
{ 
    return a > b; 
}

Sorry habe einen wichtigen Teil der Code Convention weggelassen

Es geht nicht darum alle boolschen Ausdruecke in eigene Methoden auszulagern sonder "nur" die Bedinungen die in Schleifen und Verzweigungen auftretten. Somit ist der obige Code nach den Bedingungen nicht sinnvoll. Allerdings wird es wahrscheinlich auf folgenden Code herauslaufen, da object == Null, vermutlich sehr haeufig vorkommt und isLarger auch.

Code:
private static boolean isNotMin(Double currentMin,Double number) { 
    return isNull(currentMin) || isLarger(currentMin,number); 
} 

private static boolean isNull(Object object) {
    return object == null;
}

private boolean isLarger(Double number1,Double number2) {
    return number1 > number2;
}

Zum Thema grosses Projekt. Der obigie Codestyle wurde in einem Projekt mit etwa 20 Mann Jahren eingesetzt. Kein Grosses aber auch kein kleines Projekt. Nach anfaenglicher starker Gegenwehr, wie auch hier, waren am Ende ALLE ueberzeugt, dass der Style sinnvoll.

Deswegen mein Rat probierts doch einfach mal aus. ihr werdet feststellen, dass insbesondere das Auslagern der Bedingungen dazu fuerht sich genau zu ueberlegen, welche Bedeutung die Bedingung eigentlich hat und was im Else Zweig passieren soll... Uebrigens ein Argument fuers Auslagern... :wink:
 

Saxony

Top Contributor
tfa hat gesagt.:
Es gibt aber Verfahren, die garantiert O(n*log n) sind, z.B. das in Array.sort(Object[]) verwendete Insertion-Sort.

Das Verfahren heißt genau Introsort und ist, wie ich weiter oben schon geschrieben hatte, ein Mix aus Quicksort und einem anderen Sortieralgorithmus, welcher anhand einer Bewertungsfunktion zum Zuge kommt.

Bei Arrays.sort() wird hierbei zum Quicksort der Insertionsort verwendet, welcher bei (Teil)Feldlängen < 7 seine Arbeit verrichten darf.

bye Saxony
 

Saxony

Top Contributor
Hmm,

wieso machstn nicht gleich alles double?
Das verhindert (un)kontrolliertes Autoboxing. Zudem reicht dann ein enfaches > zum Vergleich.
Und man kann es mit Java < 1.5 nutzen.

bye Saxony
 

lhein

Top Contributor
Gast(Version2) hat gesagt.:
Dies ist eine Begruendung fuehr die leere Else Bedingung!

Ja, zweifelsohne. Aber nur dann, wenn man den Entwickler für ein dummes Individuum hält.
Klar kannst Du ihn dazu zwingen, leere else-Cases zu programmieren, aber ich behaupte mal (und weiss es auch aus eigener Erfahrung), daß es dann auch genug Leute geben wird, die einfach den leeren Else-Case hincoden, aber nicht drüber nachdenken, ob das ausreichend ist.

Gast(Version2) hat gesagt.:
Fehlende Else Bedinungen sind eine sehr haeufige Fehlerquelle. Untersuchung aus dem Jahr 1978 (zugegeben sehr alt aber eindrucksvoll):
17 Prozent der ifs hatte einen else Zweig. Aber 50 bis 80 Prozent haetten fachlich einen else Zweig aufweisen muessen...
Deswegen die Verpflichtung sich ueber den else Zweig Gedanken zu machen und dies auch im Kode zu dokumentieren durchaus berechtigt.
Siehe meinen obigen Kommentar. Einen leeren Else-Case zu coden ist nicht die Versicherung gegen Bugs.

Gast(Version2) hat gesagt.:
denn man muß einfach nicht jeden Mist modularisieren.
Wieso nicht ? Wenn die Modularisierung zum Verstaendnis des Code beitraegt ?
Das tut sie aber schon im obigen Fall nicht wirklich.

Gast(Version2) hat gesagt.:
Es geht nicht darum alle boolschen Ausdruecke in eigene Methoden auszulagern sonder "nur" die Bedinungen die in Schleifen und Verzweigungen auftretten. Somit ist der obige Code nach den Bedingungen nicht sinnvoll. Allerdings wird es wahrscheinlich auf folgenden Code herauslaufen, da object == Null, vermutlich sehr haeufig vorkommt und isLarger auch.

Code:
private static boolean isNotMin(Double currentMin,Double number) { 
    return isNull(currentMin) || isLarger(currentMin,number); 
} 

private static boolean isNull(Object object) {
    return object == null;
}

private boolean isLarger(Double number1,Double number2) {
    return number1 > number2;
}
Und dann noch einen Methodennamen in Form einer Verneinung zu wählen (isNotMin), trägt zum Unverständnis noch das übrige bei. Warum hier nicht einfach die Methoden der Klasse Math genommen wurden ist auch nicht einleuchtend.
Eine eigene Methode für bla == null zu schreiben, sorry wenn ich das jetzt so sage, ist m.E. so sinnfrei wie es eben nur sein könnte.

Gast(Version2) hat gesagt.:
Zum Thema grosses Projekt. Der obigie Codestyle wurde in einem Projekt mit etwa 20 Mann Jahren eingesetzt. Kein Grosses aber auch kein kleines Projekt. Nach anfaenglicher starker Gegenwehr, wie auch hier, waren am Ende ALLE ueberzeugt, dass der Style sinnvoll.

Deswegen mein Rat probierts doch einfach mal aus. ihr werdet feststellen, dass insbesondere das Auslagern der Bedingungen dazu fuerht sich genau zu ueberlegen, welche Bedeutung die Bedingung eigentlich hat und was im Else Zweig passieren soll... Uebrigens ein Argument fuers Auslagern... :wink:

Da muß ich ganz ehrlich sagen, daß ich froh bin, so ein Monster nicht warten zu müßen.
Und um einen Entwickler zum Denken zu bewegen, sollte es nicht notwendig sein, ihn zum XtremeModularisierer zu verdammen. Modularität ja, aber bitte nur da, wo es auch wirklich Sinn macht. Einzeiler auszulagern gehört m.E. nur sehr selten zu dieser Gattung "sinnvoll".

Grüße
lr
 
G

Gast (Version2)

Gast
Einzeiler auszulagern gehört m.E. nur sehr selten zu dieser Gattung "sinnvoll".

Code:
public void bla(String s) {
    if (s != null && !s.trim.equals("")) { // So oder in Varianten hundert mal programmiert...)
        // bla
    } else {
        // bla
    }
}

obwohl Einzeiler koennte doch folgendes besser sein oder ?

Code:
// in einer Klasse StringHelper
public static boolean isEmpty(String s) {
    return s != null && !s.trim.equals("");
}

public void bla(String s) {
    if (StringHelper.isEmpty(s)) {
        // bla
    } else {
        // bla
    }
}

Ein Beispiel fuer sinnvolles auslagern...

Ein weiteres Argument fuers auslagern. Der fachliche Ablauf in einer Methode ist schnell und sehr einfach zu überblicken. Es langt z.B. beim die Debuggen einfach die Bedingung zu evaluieren, um zu testen ob sie richtig ist. (Intellij kann so was, ob eclipse das auch beherrscht weiss ich nicht). Falls eine Bedingung fehlerhaft ist kann diese gezielt(!) debugt werden und insbesondere auch relativ einfach fachlich getestet werden.


Und dann noch einen Methodennamen in Form einer Verneinung zu wählen (isNotMin), trägt zum Unverständnis noch das übrige bei. Warum hier nicht einfach die Methoden der Klasse Math genommen wurden ist auch nicht einleuchtend.

Korrekt Verneinung sollten vermieden werden. Aber sind manchmal nicht zu umgehen. Insbesondere wenn der If Zweig nicht leer sein darf (anderer Teil des Code Guides).

Math wurde nicht benutzt, da es sich um ein konstruiertes sehr einfaches Bsp. handelt...


Eine eigene Methode für bla == null zu schreiben, sorry wenn ich das jetzt so sage, ist m.E. so sinnfrei wie es eben nur sein könnte.

Im Rahmen der vorgenommenden Spezifikationen und Richtlinien ist es die logische Konsequenz, d.h. wenn man keine Ausnahmen zulassen moechte ist dies ein notwendiges übel.
 
S

SlaterB

Gast
> StringHelper.isEmpty(s)

so eine Operation verwende ich auch,
es gibt selbstverständlich sinnvolle Anwendungen

> Verneinung sollten vermieden werden. Aber sind manchmal nicht zu umgehen. Insbesondere wenn der If Zweig nicht leer sein darf

um bei obigen Beispiel zu bleiben, ich verwende sehr oft

if (!StringHelper.isEmpty(s)) {
}

wäre dir das auch schon nicht mehr akzeptabel?
Hilfsoperationen immer positiv formulieren, Negation mit !


> wenn man keine Ausnahmen zulassen moechte ist dies ein notwendiges übel.

was gegen die vorgenommende Spezifikationen spricht ;)
 

Saxony

Top Contributor
SlaterB hat gesagt.:
um bei obigen Beispiel zu bleiben, ich verwende sehr oft

if (!StringHelper.isEmpty(s)) {
}

Rüschdüsch! Ich bastel meine If Bedingung auch immer so, dass ich den Hauptteil im IF Block abarbeite und deshalb meist gar kein else Block mehr brauche.

bye Saxony
 
G

Guest

Gast
> StringHelper.isEmpty(s)

so eine Operation verwende ich auch,
es gibt selbstverständlich sinnvolle Anwendungen

> Verneinung sollten vermieden werden. Aber sind manchmal nicht zu umgehen. Insbesondere wenn der If Zweig nicht leer sein darf

um bei obigen Beispiel zu bleiben, ich verwende sehr oft

if (!StringHelper.isEmpty(s)) {
}

Es gibt tatsaechliche eine Methode

Code:
public static boolean isNotEmpty(String s) {
    return !isEmpty(s);
}

Begruendung:

Es hat sich leider gezeigt das ein "!" sehr leicht uebersehen werden kann... Ausserdem im Sinne der Spezifikation ist auch dies zwingend...

Aber auch fachlich sinnvoll denn machmal kann man einen Ausdruck nicht einfach verneinen, um die richtige fachliche Verneinung zu erhalten. Sprich der Entwickler soll sich aktiv damit auseinandersetzen, ob die Verneinung wirklich nur "!" ist oder ob es komplexer ist.

Das Argument das ein Entwickler das einfach hinschreibt trifft natuerlich auch hier zu. Es hat sich in der Praxis aber bisher nur selten gezeigt. Insbesondere in Stresssituatioen neigt man allerdings dazu.
 

lhein

Top Contributor
Gast (Version2) hat gesagt.:
Einzeiler auszulagern gehört m.E. nur sehr selten zu dieser Gattung "sinnvoll".

Code:
public void bla(String s) {
    if (s != null && !s.trim.equals("")) { // So oder in Varianten hundert mal programmiert...)
        // bla
    } else {
        // bla
    }
}

obwohl Einzeiler koennte doch folgendes besser sein oder ?

Code:
// in einer Klasse StringHelper
public static boolean isEmpty(String s) {
    return s != null && !s.trim.equals("");
}

public void bla(String s) {
    if (StringHelper.isEmpty(s)) {
        // bla
    } else {
        // bla
    }
}

Ein Beispiel fuer sinnvolles auslagern...

In dem Fall gebe ich Dir natürlich recht, aber das ist bei mir nicht unter Kategorie Einzeiler geführt, auch
wenn Du es in eine Zeile geschrieben hast.
Ein klassischer Einzeiler ist:
Code:
if (objectA != null)
.
Ich bin jedenfalls kein Freund von bildschirmfüllenden if-Bedingungen, da sind wir uns denke ich beide einig.
In solchen Fällen gehört ausgelagert.

Gruß
lr
 
S

SlaterB

Gast
Anonymous hat gesagt.:
Es hat sich leider gezeigt das ein "!" sehr leicht uebersehen werden kann...
diese Einstellung kann ja nur dazu führen, das ! im gesamten Projekt zu verbieten,

und das bei einem solchen elementaren Bestandteil der Sprache..,
so entfernt man sich immer mehr vom normalen Java, genau wie sich die Baden-Württenberger vom Hochdeutsch entfernen,
ist auch eine Sprache und in Baden-Württenberg versteht man sich,
aber lebensfähig in Gesamtdeutschland ist man damit eher nicht ;)
 

tfa

Top Contributor
Saxony hat gesagt.:
tfa hat gesagt.:
Es gibt aber Verfahren, die garantiert O(n*log n) sind, z.B. das in Array.sort(Object[]) verwendete Insertion-Sort.

Das Verfahren heißt genau Introsort und ist, wie ich weiter oben schon geschrieben hatte, ein Mix aus Quicksort und einem anderen Sortieralgorithmus, welcher anhand einer Bewertungsfunktion zum Zuge kommt.

Bei Arrays.sort() wird hierbei zum Quicksort der Insertionsort verwendet, welcher bei (Teil)Feldlängen < 7 seine Arbeit verrichten darf.

Ich schrieb Array.sort(Object[]), dort wird ein modifiziertes Merge-Sort -- nicht Quicksort -- verwendet (Insertion-Sort war falsch, keine Ahnung, wie ich darauf gekommen bin). Bei einigen anderen Sortier-Routinen (die für die primitiven Datentypen) wird in der Tat ein Quicksort verwendet. Dies macht man, da das Sortiererfahren hier nicht unbedingt stabil sein muss (im Gegensatz zu Object[]), was Introsort auch nicht ist.
 
G

Gast(Version2)

Gast
Ich bin jedenfalls kein Freund von bildschirmfüllenden if-Bedingungen, da sind wir uns denke ich beide einig.
In solchen Fällen gehört ausgelagert.

Das Problem an der Sache ist, dass die meisten Entwickler die ich bisher kenngelernt habe eher dazu neigen viel zu spaet auszulagern. Des wegen diese "harten" Regelungen. Damit der Entwickler klare Strukturen hat.

Zu "!" und "== null" und "!= null" etc.. Natuerlich ist das auf den ersten Blick hoest ungewoehnlich. Aber hier mal etwas zum Nachdenken. Der unterschied zwischen == null und == null.

Code:
...
Person person = getPerson(id)
if (person == null) {
....

Eigentlich wird hier nicht auf null geprueft sondern es fehlt eine Methode

Code:
...
if (existPerson(id)) {
....

2. Beispiel
Code:
public void bla(Person person) {
    if (person == null) {
    ...
}

Code:
public void bla(Person person) {
    if (ObjectHelper.isAssigned(person)) {
....

Beides Mal wird eigentlich auf == null geprueft. Es gibt aber erhebliche fachliche Unterschiede.
 
S

SlaterB

Gast
auch dieses Beispiel ist verständlich, auch ich benutzt sehr oft contains(objekt) statt get(object) == null,
eine weltbekannte Buchstabenfolge in Java, ein Standard, kein Argument für deine Seite ;)
 
G

Gast Version2

Gast
Hab gerade festgestellt das natuerlich

Code:
Person person = getPerson(id) 
if (person == null) { 
....

Code:
... 
if (existPerson(id)) { 
....

was anderes ist. (Verneinung fehlt) Aber die Intention sollte klar sein...
 

lhein

Top Contributor
Gast(Version2) hat gesagt.:
Code:
...
Person person = getPerson(id)
if (person == null) {
....

Eigentlich wird hier nicht auf null geprueft sondern es fehlt eine Methode

Code:
...
if (existPerson(id)) {
....

Das sehe ich ein wenig anders. Die Aussage der Methode existsPerson(id) ist schlicht nicht eindeutig.
Was würde diese Methode denn im Falle einer Exception zurückliefern? true oder false?
Viel mehr müßte der Code so aussehen:

Code:
Person person = null;
if (storage.isPersonExisting(id))
{
    person = storage.getPerson(id);
    if (person == null) 
    {
         ....person konnte wegen exception nicht ermittelt werden....handling folgt
    }
}
else
{
    ...person existiert nicht im storage...fehlermeldung
}

Du kannst in der einen Methode einfach nicht zwei fachliche Aspekte unterbringen, es sei denn Du betreibst es über das kontrollierte Werfen und Weitergeben of aussagekräftigen Exceptions.

Aber das ist nur meine Meinung, andere sehen das vielleicht auch anders :)

Gruß
lr
 
M

maki

Gast
existsPerson(id) wird eindeutigerweise eine true oder false liefern, ansonsten braucht jemand einen Englischkurs.

Eine Exception wäre möglich wenn zB. die DB nicht gefunden wird und dann gibt's ja auch keinen Rückgabewert.
Allerdings sollte es keine Exception geben wenn die Person nicht gefunden wird, ist ja schliesslich keine Ausnahme wenn man schon fragt ob's die gibt sondern eine mögliche gültige Antwort ;)

Ob getPerson(id) eine Exception wirft wenn die Person nicht existiert ist Frage der Definition, würde sagen ja wenn es schon eine existsPerson(id) Methode gibt, besserer Code.
Fange ja schliesslich auch keine IndexOutOfBoundException wenn ich durch ein Array/Collection iteriere sondern prüfe vorher ob's Sinn ergibt ein next() aufzurufen.
 
G

Gast (Version2)

Gast
Erstmal Danke an alle die sich bisher vernueftig an dieser Diskussion beteiligt haben.

Meine Intention war es Argumente gegen bzw. fuer den Code Style zu erhalten und mir selbst nochmal bewusst zu machen, wieso ich diesen Code Still verwende bzw. verwenden lasse...

Ein abschliessendes Argument fuer die strikte Auslagerung in Methoden.


Bedingungen sind haeufig fachliche Bedingugen (Ausnahme technische Infrastruktur z.B. DB Zugriffe etc.).
Sprich die Umsetzung von fachlichen Aspekten in Code.

goldene Regel:
Jede fachliche Regel (Bedingung etc.) sollte lediglich genau einmal gecodet werden. Die Vorteile liegen auf der Hand. Wartbarkeit etc.

Ich hoffe da kann jeder zustimmen...

Folge:
Es muss zwangslaeufig, wenn die Bedingungen wiederverwendet werden sollen eine irgendwie geartete Auslagerung erfolgen. Dies sollte natuerlich klar geregelt sein.

Fazit:

Wenn ein Entwickler auf die Auslagerung verzichtet und ein anderen Entwickler z.B. an der Object Schnittstelle nachschaut, ob die von ihm benoetigte Bedingung schon existiert wird er sie nicht finden, weil Sie irgendwo in den tiefen des Codes versteckt ist. Also wird er sie doppelt implementieren. Was das fuer Auswirkungen auf den Code hat kann sich glaube ich jeder vorstellen. Insbesondere bei fachlichen Aenderungen...

Also steht fuer mich fest:

Lieber einmal zuviel auslagern als einmal zu wenig....
 
S

SlaterB

Gast
wie bei dem contains bzw. exists-Beispiel ziehst du schon wieder ungebührliche Beispiele heran,

nur weil es Sinn macht, dass ein Auto Räder hat, kann man doch nicht sagen, dass jedes Fortbewegungsmittel (auch Schuhe) Räder brauchen,

nur weil es völlig richtigerweise bei emptyString, exists und fachlichenen Regeln Auslagerungen gibt,
ist das Konzept isNull(x) statt x == null doch nicht besser begründet,

die angegeben Beispiele machen Sinn, nicht nur in deinem Stil, nicht nur in Java, nicht nur beim Programmieren, nicht nur auf dem Planeten Erde

trotzdem kann man isNull(x) oder isNotMin(x,y) als gekünzelten Schwachsinn bezeichnen ;)
 

Marco13

Top Contributor
maki: Solange die Performance nicht nachprüfbar ein Problem darstellt, hat man sie gefälligst zu ignorieren und den einfachsten Code zu schreiben der möglich ist.

In mancher Hinsicht (bzw. in den meisten Hinsichten) stimmt das. Aber NICHT in diesem Fall. Es ist in diesem Fall sogar absolut unsinnig. Man sollte auf keinen Fall eine einfache Aufgabe dadurch lösen, dass man eine (in bezug auf die asymptotische Laufzeit) VIEL schwerere Aufgabe löst, nur weil man bei der Lösung der schweren Aufgabe die Lösung der einfachen Augabe mitgeliefert bekommt :noe: (Kein Mensch würde auf die hinrissige Idee kommen, eine Minimumsuche über eine Sortierung zu lösen, wenn Java nicht netterweise die Methode Arrays.sort anbieten würde...)

Knuth's "premature optimization" ist etwas anderes: Man sollte nicht irgendwelche krampfig-unverständlichen Sachen schreiben, weil sie vielleicht 3% schneller sind als die verstänliche Lösung. Optimiert wird das, wovon der Profiler sagt, dass es optimiert werden muss. Das heißt aber nicht, dass man sich beim Schreiben nicht um Laufzeiten scheren oder sich nicht über eine gute (angemessene!) Lösung des Problems Gedanken machen sollte.



Saxony: Wenn häufig gesucht werden muss, aber das Feld sich selten ändert, so ist es doch besser dieses jedes Mal zu sortieren bei Änderungen.

Das ist klar. Hat aber keinen Einfluss auf die Aussage, die ich gemacht hatte. Sortieren dauert im allgemeinen länger, aber immer mindestens genauso lange, wie die Minimumsuche. (Man könnte ja auch erwähnen: Wenn sich immer nur sehr wenige Elemente ändern, ist Bubblesort besser als Quicksort. Aber von Sonderfällen war ja erstmal nicht die Rede)



Zu der Frage, welche if-Abfragen man in eine Methode packt und welche nicht: Ich finde, das muss man von Fall zu Fall entscheiden. (Dass mein Witz(!) mit dem extrem-Methoden-Aufdröseln auch noch ernsthaft in Erwägung gezogen wurde, beunruhigt mich etwas).
In diesem speziellen Fall mal eine an die Verfechter der Methoden-Lösung gerichtete Frage: Welchen Vorteil hat es, die Methode "isNotMin" o.ä. in eine einzelne Methode zu packen? Eine Methode, die nur aus EINER Zeile besteht, und nur in EINER anderen Methode aufgerufen wird, macht IMHO keinen Sinn.

Wenn man sich so eine Methode ansieht....
Code:
/** 
 * Returns 'true' if the given 'currentMin' is null, or if the given 'number' is
 * greater than the given 'currentMin'
 *
 * @param currentMin Double The current minimum value
 * @param number Double The number to compare with the currentMin
 * @returns 'true' if the given 'currentMin' is null, or if the given 'number' is
 * greater than the given 'currentMin'
 */
private static boolean isNotMin(Double currentMin,Double number) 
{
    return currentMin == null || currentMin > number;
}
und sich beim drüberlesen und nachvollziehen erstmal spontan fragt: "Warum packt jemand so einen Scheiß in eine eigene Methode?", dann in der "min"-Methode nachsieht und erkennt, wofür die gut sein soll, sich dann aber noch fragen muss, was das mit dem Double und der null-Abfrage für einen Zweck hat, und ob die min-Methode vielleicht auch 'null' zurückliefern kann usw., dann ist das Argument "Man sieht schneller, was dort gemacht wird" schon hinfällig - und dann wäre mir eine klare, einfache Methode wie
Code:
/** 
 * Returns the minimum element of the given array
 * (+vorbedinungen...)
 *
 * @param z double The array whose minumum element will be returned
 * @returns the the minimum element of the given array
public static double Wertemin (double z[]) 
{ 
...
}
doch deutlich lieber....
 
M

maki

Gast
In mancher Hinsicht (bzw. in den meisten Hinsichten) stimmt das. Aber NICHT in diesem Fall. Es ist in diesem Fall sogar absolut unsinnig. Man sollte auf keinen Fall eine einfache Aufgabe dadurch lösen, dass man eine (in bezug auf die asymptotische Laufzeit) VIEL schwerere Aufgabe löst, nur weil man bei der Lösung der schweren Aufgabe die Lösung der einfachen Augabe mitgeliefert bekommt noe.gif (Kein Mensch würde auf die hinrissige Idee kommen, eine Minimumsuche über eine Sortierung zu lösen, wenn Java nicht netterweise die Methode Arrays.sort anbieten würde...)
Sorry Marco13, aber das sehe ich anders.

Performance Optimierungen dieser Art sind imho in 90% der Fälle rein akademischer Natur ohne wirklich die Performance zu verbessern, intellektuelle Selbstbefriedigung eben. Klar machst Spass, aber bringen tut's meistens nix und wichtig ist es schon mal gar nicht, echte Probleme gibt's dafür meistens genügend.

Wenn man natürlich vorher genau weiss, das diese Methode sehr häufig für sehr große Arrays aufgerufen wird, ist es nicht verkehrt sich darüber gedanken zu machen.
Aber wenn diese Optimierung nicht getestet und die Laufzeiten nicht verglichen werden, glaubt man doch nur die Performance verbessert zu haben ohne es wirklich zu wissen -> Hirnrissig ;)

Davon abgesehen denke ich bei begriffen wie "Minimum" immer sofort an Vergleichen, Größer/kleiner, Reihenfolge, etc. -> Sortierung ist imho nicht abwegig.

Dazu kommt das Arrays.sort() teil der Standard API ist und solange es keine guten Gründe gibt davon abzuweichen, sollte man auch nicht abweichen.

Ein Beispiel das ich bereits so erlebt habe:
Ein selbstgeschriebenes Java Framework das seine eigene "performante" String Implementierung hatte (mutables), komischerweise gab's nach der Umstellung auf standard Strings keine messbaren nachteile, nur weniger Code zum warten.
 
S

SlaterB

Gast
wenn dir ohne Gegenargument ein besseres Programm nicht gefällt,
dann ist das eine Ansicht, der man nicht mehr logisch widersprechen kann,
aber an Knuth's "premature optimization" (von Marco13 zitiert) solltest du dann nicht mit deinem Satz
'Frühzeitige Optimierung ist die Wurzel allen übels' erinnern,
sondern eher deine persönliche Sondermeinung ausdrücken ;)

du würdest wohl auch eine Queue in einer ArrayList bauen und ja nie sowas schräges wie eine LinkedList erfinden..
(wenn es sie nicht schon gäbe)


wozu eigentlich HashMap und sich über komplizierten hashCode() Gedanken machen? Liste mit contains gibts ja auch..
 
M

maki

Gast
wenn dir ohne Gegenargument ein besseres Programm nicht gefällt,
dann ist das eine Ansicht, der man nicht mehr logisch widersprechen kann,
Ich dachte eigentlich das ich Argumente gebracht hätte die meine Position erklären SlaterB.

aber an Knuth's "premature optimization" (von Marco13 zitiert) solltest du dann nicht mit deinem Satz
'Frühzeitige Optimierung ist die Wurzel allen übels' erinnern,
sondern eher deine persönliche Sondermeinung ausdrücken ;)
Meine "persönliche Sondermeinung" muss ja nicht zwangsläufig falsch sein.

Aber werfen wir doch einen Blick auf das Original von Knuth, vielleicht fällt dir ja etwas auf:
There are many senses in which a program can be
"good," of course. In the first place, it's especially good
to have a program that works correctly. Secondly it is
often good to have a program that won't be hard to
change, when the time for adaptation arises. Both of
these goals are achieved when the program is easily
readable and understandable to a person who knows
the appropriate language.
Another important way for a production program
to be good is for it to interact gracefully with its users,
especially when recovering from human errors in the
input data. It's a real art to compose meaningful error
messages or to design flexible input formats which are
not error-prone.
Another important aspect of program quality is
the efficiency with which the computer's resources are
actually being used. I am sorry to say that many people
nowadays are condemning program efficiency, telling
us that it is in bad taste. The reason for this is that we
are now experiencing a reaction from the time when
efficiency was the only reputable criterion of goodness,
and programmers in the past have tended to be so
preoccupied with efficiency that they have produced
needlessly complicated code; the result of this unnecessary
complexity has been that net efficiency has gone
down, due to difficulties of debugging and maintenance.
The real problem is that programmers have spent
far too much time worrying about efficiency in the
wrong places and at the wrong times;
premature
optimization is the root of all evil (or at least most of it)
in programming.
We shouldn't be penny wise and pound foolish, nor
should we always think of efficiency in terms of so
many percent gained or lost in total running time or
space. When we buy a car, many of us are almost
oblivious to a difference of $50 or $100 in its price,
while we might make a special trip to a particular
store in order to buy a 50¢ item for only 25¢. My point
is that there is a time and place for efficiency; I have
discussed its proper role in my paper on structured
programming, which appears in the current issue of
Computing Surveys [21].

Tatsache ist doch, das es bis jetzt weder den Beweis gibt, das Arrays.sort() wirklich zu Performanceverlust führt, noch das die "performante" Lösung wirklich auch performant ist.

Messen ist der einzige Weg, alles andere ist "aberglauben".

du würdest wohl auch eine Queue in einer ArrayList bauen und ja nie sowas schräges wie eine LinkedList erfinden..
(wenn es sie nicht schon gäbe)
Nee, würde ich nicht.
Wenn's keine LinkedList gäbe, sollte man eine schreiben ;)

wozu eigentlich HashMap und sich über komplizierten hashCode() Gedanken machen? Liste mit contains gibts ja auch..
Warum implementierst du dann nicht deine eigene, "gute" hashCode() Methode wo doch schon lange klar ist das die Standard Methode so "unperformant" ist???
 
S

SlaterB

Gast
> jetzt weder den Beweis gibt, das Arrays.sort() wirklich zu Performanceverlust führt, noch das die "performante" Lösung wirklich auch performant ist.

wenn du es nicht glaubst, dir allgemeiner Menschenverstand und O(n log n) vs O(n) nicht reichen,
dann solltest du wirklich sortieren und damit zufrieden sein,

bisher war deine Argumentation ja eher, dass es schneller ist, aber diese Geschwindigkeit die zwei Zeilen nicht wert sind
('Performance Optimierungen dieser Art sind imho in 90% der Fälle rein akademischer Natur', 'wichtig ist es schon mal gar nicht')

wenn du nun aber gar bezweifelst, dass es schneller ist, dann braucht man nicht weiter drüber nachdenken,
dich davon zu überzeugen ist mir die Mühe nicht wert

-------

bei deinem Blick fällt mir nix auf, außer dass es die Meinung von Marco13 genau widergibt:
viel Programmieraufwand + unleserlichen Code für 3% Geschwindigkeit wäre Quatsch,
<->
ein logisch einfaches simples Verfahren in 3 Zeilen statt ein einzelner Aufrufes, der eine Zeile spart aber den Rechner tausende unnötige Operationen ausführen lässt, ist sinnvoll

> Wenn's keine LinkedList gäbe, sollte man eine schreiben

dann bist du in inkosequent, in diesem Fall auf der richtigen Seite,
dann weiß ich auch nicht weiter

> Warum implementierst du dann nicht deine eigene, "gute" hashCode() Methode wo doch schon lange klar ist das die Standard Methode so "unperformant" ist???

weder finde ich hashCode() schlecht noch wußte ich bisher, dass sie unperformant ist?
 
M

maki

Gast
wenn du es nicht glaubst, dir allgemeiner Menschenverstand und O(n log n) vs O(n) nicht reichen,
dann solltest du wirklich sortieren und damit zufrieden sein,
Der allgemeine Menschenverstand neigt dazu, Details auszulassen, die unter Umständen wichtig sind.
Wie groß ist denn das Array?

Vielleicht sollten Leute mehr profilen, nur um zu sehen, was ihre sog. Optimierung wirklich gebracht hat.

Könnte dir auch ein Beispiel nennen, in dem Strings per plus aneinanderzuhängen schneller ist, als Stringbuilder/Stringbuffer zu verwenden, besser lesbar ist es auch noch.

bisher war deine Argumentation ja eher, dass es schneller ist, aber diese Geschwindigkeit die zwei Zeilen nicht wert sind
('Performance Optimierungen dieser Art sind imho in 90% der Fälle rein akademischer Natur', 'wichtig ist es schon mal gar nicht')
Gind davon aus, dass es wahrscheinlich schneller wäre, der Aufwand aber nicht lohnt, solange nicht klar ist, das man die Performance auch wiklich verbessert -> messen

Es als "Hirnrissig" zu bezeichnen die sort Methode einzusetzen ist imho wirklich daneben, solange man keine reproduzierbaren Ergebnisse hat die das auch belegen.

wenn du nun aber gar bezweifelst, dass es schneller ist, dann braucht man nicht weiter drüber nachdenken,
dich davon zu überzeugen ist mir die Mühe nicht wert
Das es theoretich zwar schneller laufen würde ist klar, ob es in der Praxis einen Unterschied macht ist eine andere Frage.


bei deinem Blick fällt mir nix auf, außer dass es die Meinung von Marco13 genau widergibt:
viel Programmieraufwand + unleserlichen Code für 3% Geschwindigkeit wäre Quatsch,
<->
ein logisch einfaches simples Verfahren in 3 Zeilen statt ein einzelner Aufrufes, der eine Zeile spart aber den Rechner tausende unnötige Operationen ausführen lässt, ist sinnvoll
Beim ersten Punkt stimme ich voll zu, beim zweiten lässt sich das aber nicht pauschal beantworten.

Der Threadtitel ist Codequalität, dass lässt sich so definieren:
1. Richtig funktionierender Code
2. Wartbarer Code
3. Performanter Code

Oft wird die Reihenfolge durcheinander gebracht.

Übrigens war es Beni, der als erstes das Argument brachte:
("No premature optimization" hat schon seine Berechtigung, aber wenn man zwei ähnlich übersichtliche Varianten hat, gibt es keinen Grund die langsamere zu wählen.)
Daraufhin kam meine Frage: "Warum denn nicht sortieren?"

weder finde ich hashCode() schlecht noch wußte ich bisher, dass sie unperformant ist?
Bloch hat es in "Effective Java" mal kurz angerissen:

Code:
// Lazily initialized, cached hashCode
private volatile int hashCode = 0; // (See Item 48)
public int hashCode() {
if (hashCode == 0) {
int result = 17;
result = 37*result + areaCode;
result = 37*result + exchange;
result = 37*result + extension;
hashCode = result;
}
return hashCode;
}

While the recipe in this item yields reasonably good hash functions, it does not yield state-ofthe-
art hash functions, nor do the Java platform libraries provide such hash functions as of
release 1.4. Writing such hash functions is a topic of active research and an activity best left to
mathematicians and theoretical computer scientists. Perhaps a later release of the Java
platform will provide state-of-the-art hash functions for its classes and utility methods to
allow average programmers to construct such hash functions. In the meantime, the techniques
described in this item should be adequate for most applications.
Speziell bei Strings scheint dieses vorgehen nicht optimal zu sein, aber für mich reichts allemal :)


Was ich rüberbringen wollte war folgendes: Es mag sicherlich "besser" sein nicht zu sortieren, ob dieses "besser" auch in der Realität sich besser auswirkt als zu sortieren, ist nicht bewiesen.

Ich hoffe Marco13 hat meine Aussage nicht als persönlichen Angriff aufgefasst, falls doch war es sicher nicht so gemeint.
 
S

SlaterB

Gast
> Wie groß ist denn das Array?
> Vielleicht sollten Leute mehr profilen, nur um zu sehen, was ihre sog. Optimierung wirklich gebracht hat.

inwiefern ist hier denn die Größe wichtig?
bei kleinen Arrays siehts für sort auch nicht rosig aus,
da überwiegt allein schon der schwerfällig Anlauf,
Arrays.sort() klont das Array, führt zahllose Unteroperation aus, erstellt zahllose lokale Variablen, Laufvariablen usw

tausende Dinge laufen unnötig im Hintergrund ab,

dagegen steht eine einzelne Schleife und 1-2 lokale Variablen,
der gesamte Ablauf in 3-4 Zeilen Code,

kürzer, schneller, ressourcenschonender, in jeder Hinsicht optimal
 
M

maki

Gast
inwiefern ist hier denn die Größe wichtig?
bei kleinen Arrays siehts für sort auch nicht rosig aus,
da überwiegt allein schon der schwerfällig Anlauf,
Arrays.sort() klont das Array, führt zahllose Unteroperation aus, erstellt zahllose lokale Variablen, Laufvariablen usw
Wenn es sich um große Datenmengen handelt und diese Methode sehr häufig aufgerufen wird, lohnt es sich darüber Gedanken zu machen, ansonsten eher nicht.
Aber solange nicht gemessen wurde, reden wir hier nur über Kopfgeburten.

Eine Methode die nur 3 mal am Tag benutzt wird zu optimieren macht wirklich nur Sinn, wenn sie vorher eindeutig zu langsam war.
Ob es sonst nun 10 Microsekunden sind oder gar 60 macht ansonsten keinen Unterschied, weder subjektiv noch objektiv.
 
S

SlaterB

Gast
du schwankst immer hin und her,
was du da zitierst habe ich geantwortet, weil du Randbedingungen ins Spiel brachtest
('Der allgemeine Menschenverstand neigt dazu, Details auszulassen, die unter Umständen wichtig sind.
Wie groß ist denn das Array?')

aber gut, vielleicht meintest du damit nicht, dass sort() bei kleinen Arrays besser dasteht,
sondern dass die Arrays so klein sind, dass es egal ist was man benutzt,
dann wäre die Diskussion in der Richtung in der Tat nutzlos

bleibt noch deine Grundaussage 'Eine Methode die nur 3 mal am Tag benutzt wird zu optimieren'
was nun Interpretation ist,

für mich sind diese 3-4 Zeilen keine aufwändige Programmierung, nichts was man im Sinne des Bären Knuts als 'Optimierungsarbeit'
bezeichnen müsste,

es ist ganz einfach die natürliche Wahl, so wie man für ein Queue kurz überlegt und dann LinkedList statt ArrayList wählt,
auch dort mag es egal sein, aber was spricht dagegen?,
es ist einfach falsch hier von verschenkter Arbeit zu sprechen, das programmiert sich doch von selbst

um wieder bei Beni zu sein:

wenn man zwei ähnlich übersichtliche Varianten hat, gibt es keinen Grund die langsamere zu wählen.

es sei denn natürlich, du siehst


double min = z[0];
for (int i = 1; i < z.length; i++) {
if (z < min) {
min = z;
}
}
return min;

als schwierigen Code an, den man eine halbe Stunde erarbeiten und besser noch testen müsste,
dann passt das langsam, dann lieber beim sort() bleiben :bae: (gemein, ich weiß)
 
M

maki

Gast
du schwankst immer hin und her,
Ne, ich glaub wir vestehen uns grad nur nicht richtig.

aber gut, vielleicht meintest du damit nicht, dass sort() bei kleinen Arrays besser dasteht,
sondern dass die Arrays so klein sind, dass es egal ist was man benutzt,
dann wäre die Diskussion in der Richtung in der Tat nutzlos
Ganz genau, jetzt verstehen wir uns wieder.

bleibt noch deine Grundaussage 'Eine Methode die nur 3 mal am Tag benutzt wird zu optimieren'
was nun Interpretation ist,

für mich sind diese 3-4 Zeilen keine aufwändige Programmierung, nichts was man im Sinne des Bären Knuts als 'Optimierungsarbeit'
bezeichnen müsste,

es ist ganz einfach die natürliche Wahl, so wie man für ein Queue kurz überlegt und dann LinkedList statt ArrayList wählt,
auch dort mag es egal sein, aber was spricht dagegen?,
es ist einfach falsch hier von verschenkter Arbeit zu sprechen, das programmiert sich doch von selbst

um wieder bei Beni zu sein:

Zitat:

wenn man zwei ähnlich übersichtliche Varianten hat, gibt es keinen Grund die langsamere zu wählen.


es sei denn natürlich, du siehst


Zitat:

int min = z[0];
for (int i = 1; i < z.length; i++) {
if (z < min) {
min = z;
}
}
return z[min];

als schwierigen Code an, den man eine halbe Stunde erarbeiten und besser noch testen müsste,
dann passt das langsam, dann lieber beim sort() bleiben bae.gif (gemein, ich weiß)

Ich seh ja ein es kein großer Aufwand ist und selbst der Code nicht groß oder unverständlich ist, allerdings ist es sicherlich auch kein kapitaler Fehler, da eine zugegebenermaßen überproportionierte aber bereits vorhande Standardfunktion zu benutzen.

Da brauch mir dann keine Gedanken machen in wieviele Methoden ich das aufbrechen will und Bugs kann ich schon mal gar keine einbauen ;)

Abgesehen davon ist Performance ist massiv überbewerted.
Leute vergessen gerne das die Hardware preise so niedrig sind, das oft ein neuer Rechner billiger kommt als ein Entwickler der optimiert.
 

Marco13

Top Contributor
Langsam wirken die Rechtfertigungsversuche trotz der zitierten schlauen Bücher ziemlich hilflos. Jetzt fehlt nurnoch das Argument: "Java ist ja sowieso SO langsam, da kommt's auf so ein kleines 'sort' auch nicht mehr an" :lol:

Aber erstmal kurz zu dem hashCode-Geplenkel: Ich nehme an, SlaterB's Aussage bezog sich nicht darauf, dass hashCode ineffizient ist (und was mit der geposteten Hashfunktion ausgedrückt werden sollte, ist mir auch nicht ganz klar) sondern eher darauf, dass man ja keine Hashsets oder HashMaps braucht: Das kann man ja alles über ArrayListen abbilden. Ein contains hat auf einer ArrayList zwar O(n), und bei einer HashSet nur O(1), aber ... die Laufzeit ist ja egal :wink:

Und das ist auch der Kern meiner Kritik: Unter "premature optimization" würde man (ich) eher sowas verstehen, wie etwa die min-Methode nicht so zu schreiben
Code:
int min = z[0];
for (int i = 1; i < z.length; i++) 
{
    if (z[i] < min) 
    {
        min = z[i];
    }
}
return z[min];
sondern so
Code:
double min = z[0];
for (int i = 1; i < z.length; i++) 
{
    min = Math.min(min, z[i]);
}
return min;
um die überflüssigen Arrayzugriffe zu sparen. (Wobei das imho garnicht mal so "premature" wäre - die Bedingung ist ganz toll in eine Methode ausgelagert, es ist übersichtlicher, und behandelt NaNs richtig... :roll: )

Was aber dafinitiv NICHT in den Bereich der premature optimization fällt, ist die Wahl des richtigen Algorithmus für die Lösung eines Problems. Und Sortieren für eine Minimumsuche ist in diesem Sinne mit Sicherheit "falsch". (Oder meinst du, D.E.Knuth hätte einen 500-Seiten-Hardcode-Mathe-Wälzer über Sorting and Searching verfasst, wenn er der Meinung wäre, man könnte "einfach alles irgendwie sortieren (so, wie es die API eben gerade anbietet)"?

Oder anders forumiert: Eine Minimumsuche über eine simple Schleife (und NICHT über eine Sortierung) zu implementieren ist für mich keine Optimierung, sondern selbstverständlich.
 

Saxony

Top Contributor
Marco13 hat gesagt.:
Code:
int min = z[0];
for (int i = 1; i < z.length; i++) 
{
    if (z[i] < min) 
    {
        min = z[i];
    }
}
return z[min];

Ähm hier am Ende doch nur return z ;)

Marco13 hat gesagt.:
Code:
double min = z[0];
for (int i = 1; i < z.length; i++) 
{
    min = Math.min(min, z[i]);
}
return min;

Ich würde sogar noch folgendes einbauen:

Code:
double min = z[0];
final int len = z. length;
for (int i = 1; i < len; i++) 
{
    min = Math.min(min, z[i]);
}
return min;


bye Saxony
 
G

Gast

Gast
Der Threadtitel ist Codequalität, dass lässt sich so definieren:
1. Richtig funktionierender Code
2. Wartbarer Code
3. Performanter Code

Oft wird die Reihenfolge durcheinander gebracht.

Das kann ich so nur absolut bestaetigen.

Mal ein Praxisbeispiel:

Es ging darum etwa 40000 Kunden zu verwalten. Bestellungen erstellen usw.

Der fachliche Code wurde großteils in Java implementiert. Leider kam jemand auf die absolute Topidee aufgrund der Datenmengen doch auch Storedprozedure in bestimmten Bereichen einzusetzen.

Das fuehrte dazu das ein Teil der Fachlichkeit sowohl in SQL als auch Java gekodet wurde. Erschwerend kam hinzu das die fachlichen Anforderungen sich durchaus von einem auf den anderen Tag geaendert haben. Dies fuehrte zu einem nicht mehr wartbaren Mix aus Java und Sql bzw. PL/SQL....

Der Hohn an der Sache... Wir haben uns dann mal hingesetzt und eine der angeblich mit java so langsamen Prozesse in Java ohne auf irgendwelche performanten Strukturen zu achten codiert. Ergebnis der Prozess lief etwa eine Stunde. Mit Stored Prozedure etwa 40 Minuten .... und sollte einmal taeglich ablaufen.... MEHR FAELLT MIR ZUM THEMA PERFORMANCE IST JA SO WICHTIG NICHT EIN!!!!!!!!!!!!

Sprich das Projekt wurde fuer 20 Minuten Laufzeit eines Prozesses gegen die Wand gefahren....

Wenn das Performace Problem auftritt, dann kann man es auch loesen ohne dafuer irgendwelche komischen Verrenckungen machen zu muessen...

Wie jemand anderes schon sagte: Meist gibt es genuegend andere Probleme zu loesen als die Performance...
 

der JoJo

Bekanntes Mitglied
mann sollte sich dennoch bei so kleinen ELEMENTAREN methoden wie der beispiel methode gedanken über performance machen, weil eine performance steigerung nach abschluss eines Projektes schwerer ist (und schlimmeren code prodoziert) als einfach während der entwicklung ein klein wenig darauf zu achten.

Wenn man immer mit der einstellung "Performance ist erstmal egal" rann geht, steht man am ende des Projektes unter umständen vor dem riesigen problem jede funktion nochmal durchgehen zu müssen, um solche performance schlucker wie die beispielmethode zu finden und zu beheben.
 
M

maki

Gast
@Marco13
Langsam wirken die Rechtfertigungsversuche trotz der zitierten schlauen Bücher ziemlich hilflos. Jetzt fehlt nurnoch das Argument: "Java ist ja sowieso SO langsam, da kommt's auf so ein kleines 'sort' auch nicht mehr an" icon_lol.gif
Vielleicht gibt's ja doch noch Hoffnung für dich...

Bis jetzt ist dein einziges Argument: Performance

Richtig?

Ich vertrete die Meinung: Performance ist Nebensache.
Was aber dafinitiv NICHT in den Bereich der premature optimization fällt, ist die Wahl des richtigen Algorithmus für die Lösung eines Problems. Und Sortieren für eine Minimumsuche ist in diesem Sinne mit Sicherheit "falsch". (Oder meinst du, D.E.Knuth hätte einen 500-Seiten-Hardcode-Mathe-Wälzer über Sorting and Searching verfasst, wenn er der Meinung wäre, man könnte "einfach alles irgendwie sortieren (so, wie es die API eben gerade anbietet)"?
Wie gesagt, ich sehe das nicht als "falsch".
Lasse mich aber gerne jederzeit durch reproduzierbare Tests (am besten realistische) vom Gegenteil belehren.

Bis dahin sehe ich das als reines Scheinargument, die zwar theoretisch einen Unterschied machen würden, in der Praxis aber nicht zum tragen kommt.
An einer Uni wäre es natürlich ein "riesen" Fehler nicht den performantesten Algo einzusetzen.

Lass mich das konkretisieren: Wenn diese Methode ein zentrales Element darstellt welche oft und für jede mögliche größe von (double)Arrays eingesetzt wird, ist deine Lösung besser, ansonsten nicht, nur aufwändiger.

Die Methode ist nicht groß, trotzdem ist eigener Code immer aufwändiger als bestehenden zu verwenden, allein die Testcases wären größer als die eigentliche Methode.


@der JoJo
mann sollte sich dennoch bei so kleinen ELEMENTAREN methoden wie der beispiel methode gedanken über performance machen, weil eine performance steigerung nach abschluss eines Projektes schwerer ist (und schlimmeren code prodoziert) als einfach während der entwicklung ein klein wenig darauf zu achten.

Wenn man immer mit der einstellung "Performance ist erstmal egal" rann geht, steht man am ende des Projektes unter umständen vor dem riesigen problem jede funktion nochmal durchgehen zu müssen, um solche performance schlucker wie die beispielmethode zu finden und zu beheben.
Wenn ich das so lese, bin ich mir sicher das du nicht für Geld programmierst, und wenn doch, dann noch nicht lange...

Ich habe in meinen 7+ Jahren Beruferfahrung kein einziges Projekt gesehen, das wegen der "schlechten" Performance fehlgeschlagen ist, weder hier noch in Übersee.

Zuerst kommt (richtige funktionsweise vorrausgesetzt) die Struktur, wenn diese gut ist, kann man jederzeit die Performance verbessern.

Ob diese Methode wirklich die Performance beeinflusst, lässt sich ohne testen sowieso nicht sagen.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben