Textdatei einlesen

  • Original von Tom9811
    Bitte schau dir meinen Code-Snipplet noch einmal an! Machen wir eine Wette um einen abend saufen, dass der if-Block abgebrochen wird?

    Und übrigens war das hier mehr oder weniger der Auslöser danach.
    Das ist von überflüssig zu erwähnen. Und vorallem habe ich nicht das Gegenteil behauptet. Es ist logisch das er aus dem if heraus geht wenn dieses sich im switch, while oder for befindet. Das break ist auch gar nicht für das if gemeint.

    Sven
    :wq! /dev/null
  • Eigentlich sollte man bessseres zu tun haben als in diese Diskussion einzusteigen, da sie so Grundsätzliches betrifft, aber es ist Urlaubszeit...

    Ein kleiner Hinweis: wer schon mal in den Sourcecode von C-Compilern geschaut hat, wird dort keinen Zusammenhang zwischen Blöcken (alles zwischen { }) und break; finden. Vielmehr ist es so, dass für folgende Keywords ein neuer Eintrag auf dem Verschachtelungsstack aufgemacht wird: for(), do, while(), switch(), evtl. if (aber nicht zwingend). Und ein break; sucht dann die nächste Schleife auf dem Stack und bastelt daraus einen goto nach außerhalb der Schleife. Und ein continue; zum nächsten Prüfen der Schleifenbedingung.

    Ob hinter dem Statement ein weiteres Statement folgt, oder eine in { } eingeschlossene Liste von Statements hat auf den fordowhileswitch() keinen Einfluß.

    Insofern ist es bei C oder C++ oder Objective-C in der Tat unsinnig davon zu sprechen, dass ein break; einen Block verläßt, weil er ein Schleifen- oder Verzweigungskonstrukt verläßt.

    Quellcode

    1. while(x) break;
    2. while(x) { break; }
    3. while(x) {{ break; }}

    sind alle völlig gleichwertig. Deshalb funktioniert auch ein if(x) break; oder if(x) { break; } und bricht die Schleife ab in die er eingebettet ist.

    -- hns
  • Nein, das war ursprünglich wirklich nicht als Spielerei gemeint. Der OP kannte ja offenbar die Wirkung von return nicht. Und wenn man dann sagt, dass es einen Block abbricht, ist das mindestens verwirrend, zumal das return ja in aller Regel in einem if-Block genestet ist.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Meine Güte, ja war mein Fehler, return bricht nicht nur code Blöcke ab sondern ganze Methoden.
    Aber verwirrt bin ich nach eurer Streiterei schon, jetzt weiß ich gar nicht mehr was exit, break, etc. machen der eine sagt jenes, der andere was anderes und dann haben doch alle das gleiche gesagt das war dann richtig nur für den anderen wieder falsch…oder so ähnlich
  • Original von asrael
    Ich hab das jetzt mal getestet:

    Quellcode

    1. 2005-08-01 08:16:44.362 ArraySpeedTest[534] time used for array1: 0:83444
    2. 2005-08-01 08:16:44.428 ArraySpeedTest[534] time used for array2: 0:52175
    3. 2005-08-01 08:16:44.478 ArraySpeedTest[534] time used for array3: 0:38645

    Wobei:
    array1: For-Schleife mit Bestimmung der laenge des Arrays im Schleifenkopf. Adressierung des Objekts mit -objectAtIndex:.
    array2: Gleiche wie array1, aber die laenge der Schleife wuerde ausserhalb ermittelt.
    array2: Durchlauf mit Enumerator.

    Hast Du dabei eigentlich die "Vorbereitungen" für den Durchlauf mit gemessen? Also Schleifenvariablen initialisieren, Enumerator erzeugen.

    Michael
  • Original von Michael
    Original von asrael
    Ich hab das jetzt mal getestet:

    Quellcode

    1. 2005-08-01 08:16:44.362 ArraySpeedTest[534] time used for array1: 0:83444
    2. 2005-08-01 08:16:44.428 ArraySpeedTest[534] time used for array2: 0:52175
    3. 2005-08-01 08:16:44.478 ArraySpeedTest[534] time used for array3: 0:38645

    Wobei:
    array1: For-Schleife mit Bestimmung der laenge des Arrays im Schleifenkopf. Adressierung des Objekts mit -objectAtIndex:.
    array2: Gleiche wie array1, aber die laenge der Schleife wuerde ausserhalb ermittelt.
    array2: Durchlauf mit Enumerator.

    Hast Du dabei eigentlich die "Vorbereitungen" für den Durchlauf mit gemessen? Also Schleifenvariablen initialisieren, Enumerator erzeugen.

    Das Enumerator erzeugen und bei den For-Schleifen die Schleifenvariable initialisieren ist mit drin, weil es ja auch mit eingehen muss, um eine aussagekraeftige Messung zu bekommen. Ansonsten passiert in allen drei Faellen das Gleiche.
    Ein Array wurde vorher mit NSNumbers gefuellt. Die Messungen entstehen beim Auslesen der Werte, wobei eine NSNumber Variable, die ausserhalb der Zeitmessung deklariert wurde, die im Array stehenden Werte zugewiesen bekommt. Die gemessene Zeit duerfte fast nur fuer die Verarbeitung der Schleife selbst draufgehen, weil die Zuweisung des Pointers nicht viel Zeit braucht, wahrscheinlich nichtmal messbar ist.

    Manfred
  • Original von asrael
    Das Enumerator erzeugen und bei den For-Schleifen die Schleifenvariable initialisieren ist mit drin, weil es ja auch mit eingehen muss, um eine aussagekraeftige Messung zu bekommen.

    Jupp, deshalb habe ich noch mal danach gefragt. Die Beschreibung der Messungen war mir da nicht genau genug. ;)

    Michael
  • Naja, einmalige Sachen werden unwichtiger, wenn die Anzahl der Durchgänge wächst. Und nur dann ist Speed überhaupt interessant. Ich würde es daher eher weglassen. Andererseits: Wenn es interessant wird, spielt es eben auch keine Rolle mehr, ob man es drin hat oder nicht.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Original von asrael
    Ich hab das jetzt mal getestet:

    Quellcode

    1. 2005-08-01 08:16:44.362 ArraySpeedTest[534] time used for array1: 0:83444
    2. 2005-08-01 08:16:44.428 ArraySpeedTest[534] time used for array2: 0:52175
    3. 2005-08-01 08:16:44.478 ArraySpeedTest[534] time used for array3: 0:38645

    Wobei:
    array1: For-Schleife mit Bestimmung der laenge des Arrays im Schleifenkopf. Adressierung des Objekts mit -objectAtIndex:.
    array2: Gleiche wie array1, aber die laenge der Schleife wuerde ausserhalb ermittelt.
    array2: Durchlauf mit Enumerator.
    Das finde ich ein überraschendes Ergebnis.

    Ich habe deshalb mal in den Source von CFlite developer.apple.com/darwin/cflite.html geschaut.

    Was mir aufgefallen ist: da finden einige Optimierungen und Fallunterscheidungen (sog. "buckets") statt. Deshalb könnte es sein, dass das Ergebnis von der Größe des Arrays abhängt.

    NSEnumerator ist keine Klasse von Core Foundation, so dass man da leider nicht nachschauen kann. Cocoa weiss vielleicht eine Lösung wie der Enumerator schneller durch die "buckets" laufen kann als dass objectAtIndex: das Objekt ausliest.

    -- hns
  • Wenn man mal davon ausgeht, dass die Arrays im Prinzip einfache verkettete Listen sind, dann ist es klar, dass man mit einem enumerator schneller ist. Denn wenn ich nach einem index in einem array frage, läuft der das ganze von Anfang an durch, bis er beim entsprechenden Index angekommen ist - desto weiter hinten der index ist, desto länger dauert's. Bei einem Enumerator ist immer nur ein einziger Befehl auszuführen, nämlich next des aktuellen elements zu liefern - das ist logischerweise schneller.

    Allerdings sind die arrays in cocoa keine reinen listen. Es sind indizierte Listen mit sprungmarken. D.h. wenn du das element 523 willst, dann läuft er nicht 523 schritte durch das Array sondern geht 5 100-er schritte bis zur 500, dann in 10-er schritten zur 520 und dann in 1-er schritten zur 523. (Alles nur Prinzip) Deshalb ist es doch nicht ganz so langsam, wie in der o.g. Reinform.

    Und allerdings sind die enumeratoren nicht einfach so da. Der will erstellt werden. Es wird ein stack angelegt (bzw. ein lineares array) mit den verweisen auf die einzelnen elemente. Dann wird immer das oberste gepopt (bzw. das nächste element ausgewählt), wenn die anfrage kommt. Das erstellen dauert halt seine zeit und deshalb ist der enumerator doch nicht ganz so schnell wie in der o.g. Reinform.

    Ich würde sagen, dass das sehr wohl von der länge abhängt und deshalb kann ich hns' Vermutung, dass die buckets im cflite der performanceoptimierung dienen, gut nachvollziehen. Vielleicht sollte man mal eine ausführliche testreihe machen, in der man die länge des arrays variiert und dann entsprechend vergleicht. Mich würde halt die Grenze interessieren...

    Max
  • @max: Gegen Fehlerteufel kann man nichts tun ;)

    Man soll die Problemstellung analysieren und die passende Methode einsetzen
    und man kann nicht sagen, dass ein Enumerator performanter ist.

    Jede Vorteile hat man, wenn man die beiden Methoden vermischt.
    Aus macfreakz wurde Apfelbeisser …
  • Original von M.A.X
    Wenn man mal davon ausgeht, dass die Arrays im Prinzip einfache verkettete Listen sind, dann ist es klar, dass man mit einem enumerator schneller ist. Denn wenn ich nach einem index in einem array frage, läuft der das ganze von Anfang an durch, bis er beim entsprechenden Index angekommen ist.....
    Ja, wenn.

    Ich bin davon ausgegangen, dass ein Array einfach ein mit malloc() beschaffter Speicherblock von id-Pointern ist, so dass man per objectAtIndex:i direkt den i-ten Pointer ausliest.

    Aber vielleicht macht Cocoa da auch noch einen Unterschied zwischen NSArray und NSMutableArray. Gerade beim MutableArray muss man einfügen und löschen können. Und das geht bei großen Arrays per verkettete Liste dann doch schneller als ein realloc() und/oder die Zeiger im Speicher rumkopieren. Jedenfalls sah der Sourcecode auf den ersten Blick entsprechend komplex aus.

    -- hns
  • RE: Textdatei einlesen

    Hallo @all,

    Ulla ulla, das geht ja ganz schön ab hier! Gerade den letzten Beiträgen konnt ich wirklich nicht mehr folgen...:)
    Naja, ich merke das mit dem NSArray und dem NSEnumerator ist eine komplexe Geschichte.
    Ich wollt das garnicht so kompliziert, meine Frage ist einfach, da es ja um Sterndaten geht, das eigentlich nur Zahlen sind, wie bekommt man die in eine Variable (vielleicht mal so gesagt)?
    Wo man einfach mit einem Index zugreift, Beisp. a(0)=2, a(1)=3, a(3)=3243.343 ect.
    In VisualBasic war das so (kannkeinerwasmitanfangenichweiss)

    Dim a(2334)

    und ausgegeben so:

    Print a(0)

    oder sowas gemacht:

    dasindjetztdiezweiwertemultipliziertdrinVariable=a(0)*a(1)

    ergab:
    dasindjetztdiezweiwertemultipliziertdrinVariable=6


    ...mit dem Dim hat man es sozusagen "dimensioniert", dh. Speicher für 2334 Variablenwerte freigemacht.

    Also: Denks einfacher, abstrakter, ich brauchs garnicht so genau, ich hab so die Vermutung (stimmts ja/nein?) das das NSArray und das NSMutableArray ganze Objecte erzeugen?? Und da denk ich mir: "Mensch das ist doch Speicherverschwendung", ihr müßt wissen, bei zB (und das wäre beinahe noch eine kleine Sterndatenbank) 500 000 Sternen (das gibt dann zB. 4*500 000 = 2.000 000 Werte).Und diese müssen(sollten) möglichst flott eingelesen(aus der Textdatei) werden(Unter 1sec wird das wohl nicht gehen?)
    Ich weiss nicht, versteh ich total was falsch, ist eine Variable schon eine Object bzw umgekehrt?




    gruß Don
  • Original von hns
    Ich bin davon ausgegangen, dass ein Array einfach ein mit malloc() beschaffter Speicherblock von id-Pointern ist, so dass man per objectAtIndex:i direkt den i-ten Pointer ausliest.

    Bei NSArray trifft das auch sicher zu , doch:

    Aber vielleicht macht Cocoa da auch noch einen Unterschied zwischen NSArray und NSMutableArray. Gerade beim MutableArray muss man einfügen und löschen können. Und das geht bei großen Arrays per verkettete Liste dann doch schneller als ein realloc() und/oder die Zeiger im Speicher rumkopieren. Jedenfalls sah der Sourcecode auf den ersten Blick entsprechend komplex aus.

    Eben, das lässt sich sinnvoll nur über ne verkettete liste machen. Und die muss indiziert und durchlaufen werden. Den statischen Fall kann man fast ausschließen, denn der wird die extreme ausnahme sein. Wenn man z.B. daten bearbeiten will, dann nimmt man dynamische (mutable) arrays.

    Noch ein interessantes Forschungsfeld: Performanceunterschied NSArray / NSMutableArray ;)
    Ist sicher ein gutes einsteigerprojekt, mal alles einzubauen und zu testen *wink*

    Max
  • RE: Textdatei einlesen

    Original von donadm
    Ulla ulla, das geht ja ganz schön ab hier! Gerade den letzten Beiträgen konnt ich wirklich nicht mehr folgen...:)
    Oh jeh - das passiert schnell mal...

    Also:
    DIM A(10) -> NSMutableArray *a=[NSMutableArray arrayWithCapacity:10];

    Das sagt dem Objekt aber nur dass es (siehe Diskussion oben) sich drauf vorbereiten soll, 10 Container zu haben. Deshalb gibt der nächste Befehl auch eine Exception, wenn man nicht mindestens einen Wert eingetragen hat.

    PRINT A(0) -> NSLog(@"%@", [a objectAtIndex:0]);

    -- hns

    PS: Man kann sogar einen Basic -> Cocoa-Translator schreiben (habe ich als ein nicht weiter verfolgtes Projekt mit dem Namen CocoaBasic herumliegen)...