Labels Evil?

Hey Leute.

Es wird ja allgemein immer erwähnt, das labels… Bööööse… sind… und man sie nicht benutzen sollte.
Da schau ich mir an wie BufferedReader so funktioniert, und bam, siehe da - es werden sogar 2 labels benutzt :smiley:

Warum haben die das hier benutzt? Konnte man das nicht anders lösen?
Oder gehts hier irgendwie um performance? Lesbarkeit?

313        StringBuffer s = null;
314        int startChar;
315
316        synchronized (lock) {
317            ensureOpen();
318            boolean omitLF = ignoreLF || skipLF;
319
320        bufferLoop:
321            for (;;) {
322
323                if (nextChar >= nChars)
324                    fill();
325                if (nextChar >= nChars) { /* EOF */
326                    if (s != null && s.length() > 0)
327                        return s.toString();
328                    else
329                        return null;
330                }
331                boolean eol = false;
332                char c = 0;
333                int i;
334
335                /* Skip a leftover '
', if necessary */
336                if (omitLF && (cb[nextChar] == '
'))
337                    nextChar++;
338                skipLF = false;
339                omitLF = false;
340
341            charLoop:
342                for (i = nextChar; i < nChars; i++) {
343                    c = cb**;
344                    if ((c == '
') || (c == '\r')) {
345                        eol = true;
346                        break charLoop;
347                    }
348                }
349
350                startChar = nextChar;
351                nextChar = i;
352
353                if (eol) {
354                    String str;
355                    if (s == null) {
356                        str = new String(cb, startChar, i - startChar);
357                    } else {
358                        s.append(cb, startChar, i - startChar);
359                        str = s.toString();
360                    }
361                    nextChar++;
362                    if (c == '\r') {
363                        skipLF = true;
364                    }
365                    return str;
366                }
367
368                if (s == null)
369                    s = new StringBuffer(defaultExpectedLineLength);
370                s.append(cb, startChar, i - startChar);
371            }
372        }
373    }```

[quote=mymaksimus]Warum haben die das hier benutzt?[/quote]weil die Programmierer der JVM auch nur Menschen und nicht perfekt sind?

[quote=mymaksimus;115072]Konnte man das nicht anders lösen?[/quote]Selbstverstädlich: in Methode auslagern oder if mit else-Zweig.

bye
TT

Ja, “Considered harmful”… Aber ich schreibe das auch so. bufferLoop-Label wird gar nicht verwendet oder?

    public static void main(String[] args) throws InterruptedException, IOException {
        // TODO code application logic here
        final long start = System.currentTimeMillis();
        final long stop = (char) Integer.parseInt(args[0]) * 60L * 1000L + start;
        System.out.println((stop - start) / 1000 / 60 + " Min.");
        for (;;) {
            for (int i = 0; i < URLS.length; i++) {
                final int fi = i;
                Thread t = new Thread() {
                    @Override
                    public void run() {
                        ByteBuffer bb = null;
                        InputStream is = null;
                        try {
                            bb = ByteBuffer.allocate(300 * 1024);
                            URLConnection urlc = new URL(URLS[fi]).openConnection();```

Was fällt denn dabei auf? Wenn man breaken kann, dann braucht man keine zusätzliche Einrückungstiefe, da der else-Zweig entfallen kann, da nicht gebreakt wurde.

Also irgendwie wird so ein Programm dann schlanker.

break break break break sorry dafür.

Viele grüße @mymaksimus  :)

naja ich meien eher, ob die einen guten grund dazu hatten ^^

Jo, um das Muster
for (i = from; i < to; i++) {
und die Lesbarkeit erhöhen nicht zu durchbrechen(/unterlaufen). Und durch charLoop: wird die Lesbarkeit erhöht.

Alles hat vor und nachteile, darüber müssten wir mal talken.

Man kann davon ausgehen, dass dieser Code vor >20 Jahren entstanden ist. Zeiten ändern sich, Personen ändern sich, Stile ändern sich, … aber Code ändert sich nicht (oder sollte sich nicht ändern) wenn er so time-tested ist, wie dieser.

Korrigiert mich bitte falls ich falsch liege, aber rein semantisch hätte man in diesem Code die Label doch weglassen können da charLoop direkt ge-break-t wird und damit das Label nicht notwendig ist und auf bufferLoop wird ja nie wieder einfluss genommen. Ich denke das ein entsprechender Compiler dies eh wegoptimiert und man sich daher nicht weiter um den Source kümmern muss (bzw was halt auch nicht getan wurde, vermutlich auf Grund der Einstellung : der Compiler machts schon richtig).
Klar gibt es viel Verbesserungspotential, z.B. StringBuilder statt StringBuffer, irgendwie das synchronized auflösen, alles n bissl strukturierter und schlanker, aber sind wir erlich : das Rad neu erfinden will auch keiner.

Wir können daraus ja n kleinen contest machen wo jeder mal so seine Implementierungs-Idee präsentieren kann und dann Vor- und Nachteile abwägen. Und vielleicht kommt man ja auch auf was “besseres”, vielleicht findet man auch guten Code in anderen Libs, aber sich den Aufwand machen nur um halt readLine() auf einem Reader zu callen … da kann man denke ich auch beruhigt mit der Standard-Variante arbeiten.

nicht einem Reader… dem BufferedReader, den so ziemlich jeder mal irgendwo haufenweise benutzt :smiley:

Aber ja, ihr habt schon recht, und stimmt, dieser code könnte schon ziemlich alt sein…

Mit Tests könnte man refactoren :wink:
Code sollte sich immer ändern können, zumindest das Design ohne die Funktion zu ändern.

Oh, da kann man viel unterscheiden, dynamische Syntax, statische Syntax, dynamische Semantik, statische Semantik, Kommentare. Ja, in dem Fall hätte man das Label weglassen können, da es in dem Bereich statisch-syntaktische Semantik liegt und eher als Kommentar anzusehen ist - ABER: so ein Label spart auch einen Kommentar! Jetzt habn die Schleifen eine Bezeichnung.

Außerdem kann sich ein anderer Progger dazu entscheiden, innerhalb der Schleife noch eine andere Schleife zu schreiben, welche die äußere Schleife (direkt) verlassen könnte. :frowning:

gut, alles well in der Praxis getestet. :slight_smile: Ich bin erst mal raus.

[QUOTE=maki]Mit Tests könnte man refactoren :wink:
Code sollte sich immer ändern können, zumindest das Design ohne die Funktion zu ändern.[/QUOTE]

[ot]
Sicher - das ist die Idealvorstellung. Aber gerade, wenn irgendwo ein „synchronized“ vorkommt, ist es IMHO schon SEHR schwer, Tests zu schreiben. Ich weiß, dass es Bemühungen gibt, multithreaded Programme testbar zu machen bzw. die Tests zu systematisieren. Und das ist auch dringendst(!) notwendig. Aber meines Wissens sind die meisten dieser Ansätze bisher eher prototypisch. Und meines Wissens kann man zumindest mit etablierten Dingen wie JUnit Thread-Safety kaum vernünftig und verläßlich testen. Abgesehen davon, dass abhängig von der Komplexität des zu testenden Codes (d.h. der Anzahl der zu testenden Fälle und Codepfade) und abhängig davon, wie omnipräsent eine Funktion in Millionen (!) von Programmen ist (wie die im Beispiel) die Testabdeckung nie so groß sein wird, wie die der Realität™. Natürlich kann man dann auf den Bug-Report warten, und hoffen, dass der Code, der im Bug-Report steht, 1:1 als nachträglich einzuführender Regression-Test herhalten kann, aber da kann die sprichwörtliche Flinte schon mit dem Bade ausgeschüttet sein. Ein bißchen related: java - Why does toString fail to produce the correct value on an immutable BigDecimal? - Stack Overflow
[/ot]

Ich kenne ehrlich gesagt keine groessere SW bei der es keine Mutlithreaded Anteile gibt, zumindest habe „meine“ Projekte sowas immer gehabt.
Trotzdem ist der Anspruch, dafuer Tests zu haben, ist auch nicht so schwer wie man meint.

An dieser Stelle mal den hinweis auf junit-toolbox: GitHub - MichaelTamm/junit-toolbox: Useful classes for writing automated tests with JUnit 4
Das kann man mit geringem Aufwand auch selber schreiben, ist oft so passiert.
Thread safety testen ist also nicht schwierig generell gesagt, besonders fuer diese eine Methode die hier gezeigt wurde, waere auch schlimm wenn sowas in heutiger SW komplett ungetest waere weil angeblich nicht testbar :wink:

Alles in allem bin ich nicht Meinung dass oben gezeigter Code „sauber“ im Sinne von lesbar ist, auch glaube ich nicht dass solcher Code untestbar waere.
Ich glaube dass man zu Zeiten des JDK 1.1 (also 1997, so alt ist dieser Code) andere Konventionen hatte, oft wurden einfach nur C Routinen „uebersetzt“ wenn es um solche Low Level Dinge ging.
Warum er nicht geandert wird?
Nun, es gibt viele Leichen im Keller von Java, insbesondere der API

Kurz & knapp: Tests helfen einem dabei solche haesslichen Codestellen zu aendern, ohne das Verhalten zu aendern. Es ist in vielen Unternehmen/Teams/Projekten ganz normal zu Refaktoren, manchmal sogar impliziter Teil der Weiterentwicklung.

[QUOTE=CyborgBeta]Oh, da kann man viel unterscheiden, dynamische Syntax, statische Syntax, dynamische Semantik, statische Semantik, Kommentare. Ja, in dem Fall hätte man das Label weglassen können, da es in dem Bereich statisch-syntaktische Semantik liegt und eher als Kommentar anzusehen ist - ABER: so ein Label spart auch einen Kommentar! Jetzt habn die Schleifen eine Bezeichnung.

Außerdem kann sich ein anderer Progger dazu entscheiden, innerhalb der Schleife noch eine andere Schleife zu schreiben, welche die äußere Schleife (direkt) verlassen könnte. :frowning:

gut, alles well in der Praxis getestet. :slight_smile: Ich bin erst mal raus.[/QUOTE]

[ot]Ich habe es bewusst nicht gepostet, aber jetzt lieferst du mir eine perfekte Vorlage …
Bei solch teils sehr qualifizierten Antworten frage ich mich wie du es bringen kannst Threads wie http://forum.byte-welt.net/java-forum-erste-hilfe-vom-java-welt-kompetenz-zentrum/java-grundlagen-fuer-anfaenger-und-umsteiger-java-se/15910-macht-folgender-quellcode.html zu erstellen die eigentlich „unter deinem Niveau“ sind …

scnr … zum gelinkten Thread : die Grundlagen kennst du eigentlich, das du einen solch simplen Code nicht deuten kannst kann ich leider nicht verstehen/nachvollziehen[/ot]

[ot]

[QUOTE=maki]Ich kenne ehrlich gesagt keine groessere SW bei der es keine Mutlithreaded Anteile gibt, zumindest habe “meine” Projekte sowas immer gehabt.
Trotzdem ist der Anspruch, dafuer Tests zu haben, ist auch nicht so schwer wie man meint.

An dieser Stelle mal den hinweis auf junit-toolbox: https://code.google.com/p/junit-toolbox/
Das kann man mit geringem Aufwand auch selber schreiben, ist oft so passiert.
Thread safety testen ist also nicht schwierig generell gesagt, besonders fuer diese eine Methode die hier gezeigt wurde, waere auch schlimm wenn sowas in heutiger SW komplett ungetest waere weil angeblich nicht testbar ;)[/QUOTE]

Ähm. Also, so einen Test mit ein paar Threads parallel laufen lassen ist nicht so ganz das, was ich meinte. Das Problem ist ja, dass die Threads ggf. über die Methode miteinander interagieren (also auf einem gemeinsamen Zustand arbeiten). Welche davon tatsächlich “erwischt” werden, wenn man ganz dumpf den Test mal mit 10 Threads laufen läßt, ist ja reine Glücksache. Um mit gutem Gewissen sagen zu können: “Das ist threadsicher” müßte man theoretisch ALLE möglichen “Muster” (systematisch!) durchprobieren, in denen die Threads ihre Instruktionen abarbeiten. Deren Anzahl wächst natürlich exponentiell (in bezug auf was? Ja, alles mögliche: Instruktionen, Threads, Synchronisationspunkte…). Also, wirklich Ahnung hab’ ich davon auch nicht, aber hatte auf der parallel 2012 - Softwarekonferenz für Parallel Programming, Concurrency und Multicore-Systeme - Karlsruhe, 23.-24. Mai 2012 :: Agenda / Programm mal einen Vortrag dazu gehört: Es gibt zwar sowas wie https://github.com/szeder/cJUnit/, oder auch multithreadedtc - A framework for testing concurrent Java applications - Google Project Hosting oder IMUnit: Improved Multithreaded Unit Testing , aber eben nichts, was so “etabliert” ist, wie JUnit. (Ich glaube oder hoffe, dass wir in ein Jahren verständnislos den Kopf schütteln werden, darüber, wie “unprofessionell” wir heute Multithreaded Unit Tests machen. Ohne statische Codeanalyse kommt man da wohl kaum auf einen grünen Zweig, aber wie gesagt, wirklich Ahnung hab’ ich da nicht, und bin vielleicht auch nicht ganz auf dem neuesten Stand…
[/ot]

[QUOTE=Sen-Mithrarin][ot]Ich habe es bewusst nicht gepostet, aber jetzt lieferst du mir eine perfekte Vorlage …
Bei solch teils sehr qualifizierten Antworten frage ich mich wie du es bringen kannst Threads wie http://forum.byte-welt.net/java-forum-erste-hilfe-vom-java-welt-kompetenz-zentrum/java-grundlagen-fuer-anfaenger-und-umsteiger-java-se/15910-macht-folgender-quellcode.html zu erstellen die eigentlich „unter deinem Niveau“ sind …

scnr … zum gelinkten Thread : die Grundlagen kennst du eigentlich, das du einen solch simplen Code nicht deuten kannst kann ich leider nicht verstehen/nachvollziehen[/ot][/QUOTE]

[OT]Also

  1. eigentlich verstehe ich Programmcode in Java ganz gut, wollte aber mehr über die Festplatte erfahren,
  2. ich wollte mit dem Thema, dass andere und neue mal ein paar Beiträge schreiben und sie „anlocken“,
  3. das war kein „Hacking“,
  4. schöne Ostern. :slight_smile:

Ich verstehe nicht, warum unser Forum nicht mehr/häufiger benutzt wird, obwohl wir wirklich gut sind, und stattdessen wahrscheinlich ein anderes Forum verwendet wird. :frowning: Dabei sind wir freundlich usw. :slight_smile: Niveau gibt es nicht, Gut und Böse gibt es auch nicht, nur den Osterhasen. :lol: Was meinst du dazu? ::ele[/OT]

[OT]Ich finde das Niveau deiner Beiträge lässt größtenteils zu wünschen übrig.[/OT]

Der Code im JDK ist zum großteil nicht ‚clean‘, liegt aber wie schon erwähnt wurde auch daran, dass er so alt ist.
Andere Gründe könnten Performance-Tweaks etc. sein, die man nicht auf den ersten Blick sieht.

Man kann an dem Stück Code einiges für die Lesbarkeit tun, kostet dann an ein paar Ecken natürlich ein paar Operationen mehr. omitLF ist so ein kandidat. Will man ein || pro Schleifendurchlauf mehr berechnen oder spendiert man die Variable? Ich bin hier eher für die Lesbarkeit: das Rausziehen von der Variable aus der Schleife kriegt auch ein halbwegs intelligenter Compiler hin.
Tieferes Refactoring in dem Code wird durch die verschachtelten Variablen ziemlich frickelig und ist anfällig für Fehler (ohne Unit-Tests würde ich hier nichts anfassen).
Deutlich sieht man das bei der charLoop.
Die Schleife an sich schiebt das i bis zum Zeilenende, und detektiert zusätzlich noch \r.
Der Variablenname i ist für den großen Scope den er einnimmt auch nicht gut gewählt.
skipLF wird für meinen Geschmack viel zu spät gesetzt, die Zuweisung gehört IMO in die schleife.
Schaut man sich anschließend die schleife an, macht die selber schon zu viel: Zeilenende suchen und Char am Zeilenende auswerten könnte man splitten.
Die Behandlung von einer Zeile im if(eol)-Block kommt auch viel zu spät und streckt den Scope von der c-Variable unnötig.
Den StringBuffer könnte man auf den ersten und zweiten Blick auch früher initialisieren (immer?) und sich die null-checks damit sparen.

ABER: so ein Label spart auch einen Kommentar! Jetzt habn die Schleifen eine Bezeichnung.

Am besten markierst du jede Schleife mit einem Label, deine Kollegen werden dich für den lesbaren Code lieben ::slap1.

[OT][QUOTE=mymaksimus][OT]Ich finde das Niveau deiner Beiträge lässt größtenteils zu wünschen übrig.[/OT][/QUOTE]

Vergiss nicht, dass ich schon etwas länger dabei bin als du. ;)[/OT]

Genug Spam für heute.

@ TT : Danke für deinen Beitrag.

[QUOTE=CyborgBeta][OT]

Vergiss nicht, dass ich schon etwas länger dabei bin als du. ;)[/OT]
[/QUOTE]

Soll heißen?

Jo, ist immerhin Ostern…

  1. ich hab mehr Erfahrung als sie/er,
  2. ich bin schlauer,
  3. ich stelle die „Erfinder“ der JRE nicht in Frage,
  4. ich weiß, dass obiger Code richtig ist, nicht verbessert werden kann, kurz gehalten ist und allen Anforderungen genügt.

Genügt das als Antwort? Wieso soll ich jemanden (in der 11. Klasse?) das erklären und begründen, wenn mir „unterstellt“ wird, meine Beiträgen seien niveaulos? Dann mach’ deinen Kram alleine.

Sorry und Danke. over and out