Unklarheiten zu Swift

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Du hast eigentlich meine einzige Frage gar nicht beantwortet.

    Es ist auch egal, ob das nachgerüstet wird. Denn es gibt natürlich noch viele andere Methoden, auch Custom, die ich haben möchte.

    Ich will auch keine generische Funktion haben. Oder darf ich Swift nur benutzen, wenn ich OOP wegwerfe? Bisher war es ja so modern wie die 70er. Wir nähern uns langsam der Modernität der 60er.

    Ich lerne insgesamt aus deinem Beitrag, dass ich a) Swift-Arrays offenbar gar nicht allgemein erweitern kann und b) ich aber OOP wegwerfen kann, wenn ich auf Arrays arbeiten möchte.

    Sollte sich das bewahrheiten und nicht nur an unser beider Unfähigkeit liegen, dass einigermaßen knapp in Swift zu formulieren, ist die Sprache endgültig für den Mülleimer. Das ist ja nun wirklich kein Anliegen, was irgendwie besonders wäre.
    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"?
  • Amin Negm-Awad schrieb:

    Du hast eigentlich meine einzige Frage gar nicht beantwortet.


    Ist das immer noch unklar?

    Letztlich geht es hier ja nach der Frage von TheFuriousLion nur darum, wie man es hinschreibt, und dabei in erster Linie um Bequemlichkeit. Die Funktionalität ist ja klar und ist im Spezialfall mit Objekt-Pointern auch identisch zu containsObject in NSArray.

    Swift-Arrays sind im Gegensatz zu NSArrays aber nicht darauf beschränkt, ausschließlich Pointer zu enthalten, sondern die können auch elementare oder zusammengesetzte Typen direkt enthalten (schneller, kaum Speicherplatz-Overhead).

    containsObject macht in der Grund-Klasse Array also schlicht keinen Sinn, weil in Swift Arrays nicht nur Objekte enthalten können, sondern auch alle anderen Typen.

    Entsprechend kann man die Suche nach einem Objekt in einem Array<class> entweder explizit formulieren (wobei ich vermuten würde, daß der Ansatz mit einem Filter tatsächlich ein neues, temporäres Array erzeugt – eine einfache Suche wäre wohl besser), oder eben einen anderen Weg nehmen:

    • Eine spezialisierte generische Klasse ObjectArray<class> von Array<type> ableiten, in der man dann Objekt-Array-spezifische Zusatzmethoden bereitstellen kann, und dabei eben auch ein Äquivalent zu containsObject.

    • Eine generische Funktion wäre eine ander Möglichkeit, für die man nicht mal eine separate Klasse bräuchte. Die würde sofort für alle Arrays mit Objekt-Pointern funktionieren, egal, wo die herkommen, aber halt mit Funktions- und nicht mit Methoden-Syntax beim Aufruf, also contains(myarray, myobj) statt myarray.contains(myobj), aber ansonsten mit identischer Funktionalität.

    Dafür ein Protokoll zu nehmen wäre wahrscheinlich nicht mal so sinnvoll, weil alle in Frage kommenden Arrays ja auch damit immer noch abgeleiteten Klassen zugehören müßten, soweit ich sehe.

    Und es kann natürlich auch noch andere Möglichkeiten geben, die ich noch nicht kenne.

    Amin Negm-Awad schrieb:

    Ich will auch keine generische Funktion haben. Oder darf ich Swift nur benutzen, wenn ich OOP wegwerfe? Bisher war es ja so modern wie die 70er. Wir nähern uns langsam der Modernität der 60er.


    Na, gottseidank kommst Du ja ganz ohne Polemik aus. 8)

    Tatsächlich sind generische Funktionen eine zusätzliche Ausformung desselben Gedankens, der hinter dem OO-Konzept steht: Grundlegende Mechanismen sauber zu abstrahieren und zu generalisieren, wo das möglich ist, um die Pflegbarkeit zu verbessern, mehrfache Implementierungen des immer selben Mechanismus möglichst überflüssig zu machen und den Code zu vereinfachen.

    Sie sind eine zusätzliche Möglichkeit, keine Einschränkung!

    Amin Negm-Awad schrieb:

    Ich lerne insgesamt aus deinem Beitrag, dass ich a) Swift-Arrays offenbar gar nicht allgemein erweitern kann


    Soweit ich das verstehe, ist Ableitung in Swift die einzige Möglichkeit, neue Komponenten oder Methoden zu einer schon existierenden Klasse hinzuzufügen.

    Wenn man bestehende Klassen nachträglich noch modifizieren können will, erzwingt das einen erheblichen Laufzeit-Overhead bei allen Klassen, egal, ob diese Möglichkeit jetzt wirklich ausgenutzt wird oder nicht, weil dann bei jedem einzelnen Zugriff dynamische Lookups aller Methoden und Komponenten zwingend notwendig sind, denn da könnte ja jederzeit ein Eingriff erfolgt sein.

    Es wäre schön, wenn man solche Möglichkeiten umsonst bekommen könnte, aber tatsächlich sind die inhärent ziemlich teuer.

    Funktionell können generische Funktionen allerdings eine ähnliche Aufgabe erfüllen, aber ohne den Laufzeit-Overhead bei allen Klassen, und sogar noch allgemeiner, weil sie nicht nur auf Objekte beschränkt sind.

    Amin Negm-Awad schrieb:

    und b) ich aber OOP wegwerfen kann, wenn ich auf Arrays arbeiten möchte.


    Nein, überhaupt nicht. Wie kommst Du auf die komische Idee? Arrays sind in Swift vollständig in die Objekt- und Klassen-Mechanik eingebettet.

    Und dabei können sie konsistent ohne Spezialbehandlung für Objekte wie auch für andere Typen eingesetzt werden und funktionieren überall gleich.
  • Ich komme auf die Idee, weil du eine Funktion (nicht Methode, um das begrifflich klar zu machen) nennst.

    Übrigens hast du die Frage immer noch nicht beantwortet: Wie häufig muss ich das Ding installieren? Bitte keinen langen Romane mit persönlichen Anmerkungen. Einfach mal ne Antwort.

    Und natürlich geht es nicht um eine einzelne Methode. Es ist ja nun nichts Unanständiges zu fragen, wie man Arrays erweitert.

    Und wieso ist das in Objective-C nicht so teuer?

    Und wieso ermöglicht generische Programmierung mehr, wenn man nicht einmal -containsObject: implementieren kann?
    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"?

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von Amin Negm-Awad ()

  • Amin Negm-Awad schrieb:

    Ich komme auf die Idee, weil du eine Funktion (nicht Methode, um das begrifflich klar zu machen) nennst.


    Das ist eine von mehreren Möglichkeiten.

    Die, die Du offenbar meinst, geht übrigens doch auch in Swift (hatte ich übersehen gehabt) und sieht dann wohl so aus (das müßte mal jemand mit der Beta ausprobieren – TheFuriousLion?):

    Quellcode

    1. extension Array<theclass where theclass: AnyObject> {
    2. func contains(that: theclass) -> Bool {
    3. for it in self {
    4. if it === that {
    5. return true
    6. }
    7. }
    8. return false
    9. }
    10. }


    Diese Extension muß meines Wissens nur inkludiert sein und fügt dann allen Arrays, die tatsächlich Objekte enthalten (und nicht andere Typen), die Methode contains() hinzu (und ggf. weitere Methoden, Komponenten. Initializer und so weiter). Zumindest soweit ich das bisher sehe, ist der Operator === normalerweise nur für Objekte definiert, deshalb die Spezialisierung auf Objekt-Arrays. Notfalls könnte man natürlich den Operator auch für die anderen Typen überladen, dann könnte die Einschränkung wohl auch noch entfallen.

    Danach kann überall auf beliebigen Objekt-Arrays ganz normal so gearbeitet werden:

    Quellcode

    1. if myarray.contains(myobject) { DoSomethingWith(myobject) }


    Siehe dazu:
    developer.apple.com/library/pr…_language/Extensions.html

    Amin Negm-Awad schrieb:

    Übrigens hast du die Frage immer noch nicht beantwortet: Wie häufig muss ich das Ding installieren? Bitte keinen langen Romane mit persönlichen Anmerkungen. Einfach mal ne Antwort.


    Nur ein Include (z.B. in einem Standard-Include-File) und das sollte schon alles sein.

    Amin Negm-Awad schrieb:

    Und wieso ist das in Objective-C nicht so teuer?


    Ist es zur Laufzeit ja; Das ist ja gerade einer der Gründe, warum Swift überhaupt existiert.

    Bei statischen Klassen (die also nicht über die Runtime gehen müssen) müßten in Swift auch Extensions "Laufzeit-kostenlos" bleiben können – effektiv ist der Vorschlag für meine Extension oben funktionell äquivalent zu einer generischen Funktion, nur mit ein bißchen Syntax-Zucker drübergestreut, damit sie netter aufrufbar ist und sich an der Aufrufstelle nicht mehr von anderen Methoden unterscheidet. Im Code kann dabei ggf. exakt dasselbe herauskommen.

    Generische Funktionen sind gewissermaßen "freie Extension-Methoden", die ggf. über beliebige Grundtypen und Klassen hinweg einsetzbar sind. Bis auf ein bißchen Syntax-Unterschied macht der Compiler wohl dasselbe mit ihnen wie mit zusätzlichen Methoden.

    Ob und wie Swift auch Laufzeit-dynamische Extensions von Runtime-basierten Klassen unterstützt, bliebe zu untersuchen, sollte aber bei identischer Syntax transparent möglich sein. Und bei alledem ist natürlich interessant, was für Code da letztlich eigentlich generiert wird (natürlich mit allen Vorbehalten in diesem frühen Stadium).

    Amin Negm-Awad schrieb:

    Und wieso ermöglicht generische Programmierung mehr, wenn man nicht einmal -containsObject: implementieren kann?


    Natürlich kann man das. Und offenbar eben doch auch nachträglich als Zusatz zu einer Standard-Klasse (bzw. zu einer bestimmten Spezialisierung davon).
  • -containsObject: prüft nicht auf Identität, sondern auf Gleichheit.

    Wenn ich das richtig sehe, wirfst du die gerühmte Typsicherheit von Swift weg. Jetzt frage ich mich aber, ob wirklich für jede Klasse, die in einem Array stecken kann der == Operator gegen AnyObject definiert ist. Immerhin könnte der Operator ja mit verschiedenen Typen überladne sein.

    Dann lässt sich das aber nur noch zur Laufzeit entscheiden. Hmmm, … Eigentlich ist das jetzt ja schon fast Objective-C – nur halt in einer gräßlichen Syntax.
    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"?
  • Amin Negm-Awad schrieb:

    -containsObject: prüft nicht auf Identität, sondern auf Gleichheit.


    Auch kein Problem: Wenn man nicht exakt dieses, sondern nur ein vergleichbares Objekt finden will, benutzt man einfach nur den == Operator anstatt ===. Ansonsten (fast) alles wie gehabt.

    Amin Negm-Awad schrieb:

    Wenn ich das richtig sehe, wirfst du die gerühmte Typsicherheit von Swift weg.


    Nein; theclass muß zwischen dem Array und dem gesuchten Objekt exakt zusammenpassen, sonst ist die Methode nicht aufrufbar. Der where-Clause sagt nur, was theclass alles sein darf und was nicht. In diesem Fall muß es wirklich eine Klasse sein und kein Basis- oder Composit-Typ.

    Wenn man mit == arbeiten will, müßte der where-Clause wohl nicht auf AnyObject, sondern auf Equatable einschränken (wo dann die Grundtypen schon mal drin sein sollten, zusammen mit vergleichbaren Objekten (die also den ==-Operator überladen) – ich weiß jetzt nicht aus dem Stegreif, ob z.B. Structs einen Default-Vergleich mitbekommen oder ob man den bei Bedarf auch dort selbst hinzufügen muß).

    Amin Negm-Awad schrieb:

    Jetzt frage ich mich aber, ob wirklich für jede Klasse, die in einem Array stecken kann der == Operator gegen AnyObject definiert ist. Immerhin könnte der Operator ja mit verschiedenen Typen überladne sein.


    Zumindest so wie ich es hingeschrieben habe, blockt der Compiler schon ab, wenn die Element-Klasse des Arrays und die Klasse des Vergleichsobjekts nicht zusammenpassen. Wenn man beim Vergleichsobjekt statt theclass z.B. otherclass deklarieren würde, müßte der Compiler beim Aufruf prüfen, ob es für die Kombination theclass und otherclass einen gangbaren Vergleich (also eine Überladung) gibt. Bei C++ würde der Compiler auch noch die erlaubten Casts und Konvertierungen automatisch berücksichtigen, aber ich glaube, daß Swift hier strikter ist. Mehr als ein vererbter Basisklassen-Vergleich ist da wahrscheinlich compilerseits nicht drin.

    Amin Negm-Awad schrieb:

    Dann lässt sich das aber nur noch zur Laufzeit entscheiden.


    Wieso? Die Klasse des Vergleichsobjekts ist doch in der Regel genauso bekannt wie die Element-Klasse des Arrays, also kann der Compiler in diesen (häufigen) Fällen schon vorher feststellen, ob das geht oder nicht

    Wenn man in Swift mit Objective-C-Klassen und NSArrays hantiert, kriegt man die Typsicherheit natürlich nicht mehr im gleichen Ausmaß geprüft, weil die genauen Klassen dann zur Compilezeit ggf. noch gar nicht bekannt sind.

    Amin Negm-Awad schrieb:

    Hmmm, … Eigentlich ist das jetzt ja schon fast Objective-C


    Nein, ist es nicht. Der Löwenanteil der ganzen Geschichte läuft zur Compilezeit ab, und heraus kommt (bzw. kann zumindest kommen) reiner statischer Code, solange Dynamik nicht explizit oder implizit angefordert wird.

    Amin Negm-Awad schrieb:

    – nur halt in einer gräßlichen Syntax.


    Da scheiden sich offensichtlich die Geister...! ;)

    Ich finde die Swift-Syntax wesentlich schicker, gerade auch, weil es keine separate, konzeptionell inkompatible Teilsyntax mehr gibt, die sich auf völlig anderen Wegen um Nicht-Objekte kümmern muß.

    Aber Geschmackssache bleibt natürlich Geschmackssache. Wobei der Geschmack ja manchmal auch mit dem Essen kommt – oder natürlich manchmal auch vergeht...! 8)

    Insofern bin ich zwar ziemlich sicher, daß ich gerne in Swift arbeiten werde, aber sicher weiß ich das auch erst, wenn ich es eine Weile getan haben werde.
  • Ich verstehe noch nicht, wie das funktionieren soll:

    Wenn ich ein Array von Strings habe und dann contains( Int ) mache, wird der Generic auf Int instantiert. Hier kann er noch feststellen, dass it == that verschiedenen Typs sind. (Letztlich egal, es kommt nur darauf an, dass es für dieses Typpaar überladen ist.)

    Wenn ich ein Array von AnyType habe oder auf AnyType instantiere, kommt es darauf an, ob das entsprechend überladen ist. Wenn diese Bedingung in Subklassen erst erfüllt ist, kommt es zu einem unberechtigten Fehler.

    Das dynamische Dispatching ist auch keine Arbeit. Entgegen deiner Annahme, dass immer ein kompletter Look-Up vorgenommen werden muss, weil sich etwas geändert haben könnte, ist es so, dass es linear gecacht wird, weil das RTE weiß, wenn sich etwas verändert hat. (Was natürlich so gut wie nie vorkommt.)

    Die Anmerkung zur Syntax war genau so gemeint: Es gibt wenig objektive Argumente für eine bestimmte Syntax. Also ist das häufig gehörte Argument, dass die Syntax von Swift() besser sei, genau so unsinnig, wie das Gegenteil. Advocatus diaboli.
    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"?
  • Amin Negm-Awad schrieb:

    Ich verstehe noch nicht, wie das funktionieren soll:

    Wenn ich ein Array von Strings habe und dann contains( Int ) mache, wird der Generic auf Int instantiert. Hier kann er noch feststellen, dass it == that verschiedenen Typs sind. (Letztlich egal, es kommt nur darauf an, dass es für dieses Typpaar überladen ist.)


    Grundsätzlich wäre das der Mechanismus bei flexiblerer Definition (theclass und otherclass), während bei meiner Beispiel-Extension sofort ein Fehler käme, weil String nicht Int ist (beides mal theclass).

    Amin Negm-Awad schrieb:

    Wenn ich ein Array von AnyType habe oder auf AnyType instantiere, kommt es darauf an, ob das entsprechend überladen ist. Wenn diese Bedingung in Subklassen erst erfüllt ist, kommt es zu einem unberechtigten Fehler.


    Nein, der Fehler ist völlig korrekt. Genau darin besteht ja die Hilfe durch den Compiler, daß er nämlich sofort merkt, daß das nicht zusammenpaßt. Effektiv schmeißt er auf die Ausrede "Aber vielleicht bringen die Objekte ja doch noch den Operator von einer Subklasse mit!" einen "Da könnte ja jeder kommen!"-Fehler. ;)

    Wenn ich will, daß der Compiler das erlaubt, muß ich auch dafür sorgen, daß die tatsächlich angegebenen Klassen die angeforderten Operationen zulassen.

    Das ist ja gerade der Witz bei Compiler-Prüfungen.

    Wenn ich das explizit nicht haben will, muß ich dem Compiler explizit sagen, daß das wirklich erst zur Laufzeit geprüft werden soll, was aber zumindest in Swift-Code dann zu einer fatalen Exception führen kann, wenn man nicht wirklich sehr genau weiß, was man tut.

    Wobei ich das Buch über die Einbindung von Objective-C in Swift noch vor mir habe; Da müssen natürlich sinnvolle Regeln existieren, wie bei gemischtem Einsatz die konzeptionell unterschiedlichen Ansätze gerade auch bei der Typsicherheit gehandhabt werden.

    Amin Negm-Awad schrieb:

    Das dynamische Dispatching ist auch keine Arbeit. Entgegen deiner Annahme, dass immer ein kompletter Look-Up vorgenommen werden muss, weil sich etwas geändert haben könnte, ist es so, dass es linear gecacht wird, weil das RTE weiß, wenn sich etwas verändert hat. (Was natürlich so gut wie nie vorkommt.)


    Ich hatte ja auch schon erwähnt, daß die Lookups teilweise gecached werden können. Aber selbst das ist immer noch langsamer als schon der langsamste virtuelle Aufruf in C++ und wahrscheinlich auch in Swift (außer natürlich, wenn man in Swift Runtime-Objekte aufruft).

    Das dynamische Dispatching ist also sehr wohl einiges an Arbeit; Vor allem erfolgt es in Objective-C zwangsweise bei allen Methoden-Aufrufen, ohne Ausnahme, soweit ich weiß.

    Bei C++ und höchstwahrscheinlich auch bei Swift können Methoden je nach Deklaration nicht nur direkt aufgerufen werden (ohne Jumptable-Indirektion), sondern bei entsprechender Deklaration sogar an der Aufrufstelle komplett aufgelöst werden und der Code als Inline komplett mit dem Aufrufer-Code verschmolzen werden (bis hin zur durchgehenden Register-Optimierung). Es ist dann also nicht mal nur ein schnellerer Aufruf als über die Runtime, sondern ggf. gar kein Aufruf mehr, wenn die Klassen-Definition und der Aufruf das erlauben.

    Im Extremfall kann ein Methoden-Aufruf komplett verschwinden (wenn die Methode z.B. eine Fallunterscheidung enthält, von der der Compiler bei einem bestimmten Aufruf schon wissen kann, daß keiner der Fälle eintritt – Xcode/LLVM kann diese Art der Optimierung ja heute schon) oder nur noch ohne Call einen oder wenige Maschinenbefehle erzeugen und dabei den kompletten Parameterübergabe-Mechanismus komplett einsparen.

    Amin Negm-Awad schrieb:

    Die Anmerkung zur Syntax war genau so gemeint: Es gibt wenig objektive Argumente für eine bestimmte Syntax. Also ist das häufig gehörte Argument, dass die Syntax von Swift() besser sei, genau so unsinnig, wie das Gegenteil. Advocatus diaboli.


    Es gibt schon viele objektive Argumente in die eine wie die andere Richtung; Die Subjektivität kommt eigentlich primär dadurch hinzu, daß man die Relevanz und das Gewicht der diversen Argumente unterschiedlich bewertet. Wobei auch unterschiedliche Bewertungen ja jeweils trotzdem völlig legitim sein können – vom jeweiligen Standpunkt aus gesehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RegExpressive ()

  • RegExpressive schrieb:

    Ich hatte ja auch schon erwähnt, daß die Lookups teilweise gecached werden können. Aber selbst das ist immer noch langsamer als schon der langsamste virtuelle Aufruf in C++ und wahrscheinlich auch in Swift (außer natürlich, wenn man in Swift Runtime-Objekte aufruft).


    Ja, aber spielt das in der Praxis tatsächlich eine Rolle? Ich mach' jetzt seit mehr wie 10 Jahren Objective-C, davor C++ und/oder Java. Und außer in den Anfangsjahren von Java hatte ich in keiner Sprache großartige Performance-Probleme, die auf solchen Sachen wie virtuelle Methode oder nicht zurückzuführen waren. Wenn's ein Performance-Problem gab, dann war's der Algorithmus und dann hätt's ein direkter Methodenaufruf auch nicht rausgerissen. Schönes Beispiel war z.B. die String-Konkatenation in Java. Die kostet und da konnte man sich an entscheidenden Stellen die Performance kaputtmachen. Vollkommen unabhängig davon, ob der Methoden-Aufruf in Java jetzt um 217% langsamer war wie in C++.

    schönen Gruß

    gandhi
  • Klar gibt's das, keine Frage. Und für so ein Problem ist dann u.U. Objective-C nicht geeignet (Nicht jedes Problem ist ein Nagel). Aber in einer Grundsatzdiskussion immer auf den schnelleren Methodenaufruf zu verweisen ist m.E. müßig und trifft nicht den Kern der Debatte. Für die allermeisten Anwendungen ist das nämlich schnurzegal.

    ciao

    gandhi
  • gandhi schrieb:

    Klar gibt's das, keine Frage. Und für so ein Problem ist dann u.U. Objective-C nicht geeignet (Nicht jedes Problem ist ein Nagel). Aber in einer Grundsatzdiskussion immer auf den schnelleren Methodenaufruf zu verweisen ist m.E. müßig und trifft nicht den Kern der Debatte. Für die allermeisten Anwendungen ist das nämlich schnurzegal.

    Ja, genau.

    Ist aber auch so, dass Performance auch mit Energiebedarf zusammenhängt. 2% mehr Performance merkt man bei einer durchschnittlichen App wahrscheinlich eher nicht, aber 2% Akkulaufzeit vielleicht schon.
    C++
  • zerm schrieb:

    gandhi schrieb:

    Klar gibt's das, keine Frage. Und für so ein Problem ist dann u.U. Objective-C nicht geeignet (Nicht jedes Problem ist ein Nagel). Aber in einer Grundsatzdiskussion immer auf den schnelleren Methodenaufruf zu verweisen ist m.E. müßig und trifft nicht den Kern der Debatte. Für die allermeisten Anwendungen ist das nämlich schnurzegal.

    Ja, genau.

    Ist aber auch so, dass Performance auch mit Energiebedarf zusammenhängt. 2% mehr Performance merkt man bei einer durchschnittlichen App wahrscheinlich eher nicht, aber 2% Akkulaufzeit vielleicht schon.


    2% von 10% welche die app überhaupt nutzt sind dann aber nur noch 2 promille ;)
  • gandhi schrieb:

    Ja, aber spielt das in der Praxis tatsächlich eine Rolle? Ich mach' jetzt seit mehr wie 10 Jahren Objective-C, davor C++ und/oder Java. Und außer in den Anfangsjahren von Java hatte ich in keiner Sprache großartige Performance-Probleme, die auf solchen Sachen wie virtuelle Methode oder nicht zurückzuführen waren. Wenn's ein Performance-Problem gab, dann war's der Algorithmus und dann hätt's ein direkter Methodenaufruf auch nicht rausgerissen. Schönes Beispiel war z.B. die String-Konkatenation in Java. Die kostet und da konnte man sich an entscheidenden Stellen die Performance kaputtmachen. Vollkommen unabhängig davon, ob der Methoden-Aufruf in Java jetzt um 217% langsamer war wie in C++.


    Wie C++ FTW schon gesagt hat, kommt es darauf an; Wenn Du hauptsächlich Oberflächen-nahen Code hast, in dem zur Laufzeit zahlenmäßig relativ wenige Schleifendurchläufe oder Callbacks vorkommen, kommt es meistens nicht so sehr darauf an.

    Deshalb sollte man die reine Code-Performance in solchen Fällen auch wirklich nicht überbewerten.

    Allerdings ist es halt nicht immer so einfach. Wenn man wirklich größere Datenmengen verarbeiten muß und man dabei trotzdem saubere Abstraktion haben will oder muß, also z.B. viele Objekte, die wiederum aus diversen Unter-Objekten zusammengesetzt sind und auf denen der Code intensiv arbeitet, dann schlägt der Overhead für die Objekt-Interaktion ggf. deutlich zubuche und kann einen größeren Anteil am insgesamt ausgeführten Code ausmachen. Und dann kann es ein erheblicher Vorteil sein, wenn z.B. eben im kompilierten Code die Komponenten-Objekte nur noch wie simple Structs erscheinen und die Methoden nur noch als ein paar Maschinenbefehle direkt im aufrufenden Code.

    Wenn man Tausende oder Millionen von Objekten mit vielen Sub-Objekten in großen Transaktionen bearbeitet, kann der reine Overhead der Methoden-Aufrufe sonst schon deutlich zubuche schlagen.

    Es ist ja kein reiner Zufall, daß selbst OS X im Kernel für das IOKit auf C++ setzt und nicht auf Objective-C, und viele komplexere bzw. Numbercrunching-Software eben auch. Auch WebKit (also Safari und alle anderen Browser, die es benutzen) wäre wahrscheinlich merkbar langsamer, wenn es in Objective-C implementiert wäre, denn gerade dort wird beim Laden und Bearbeiten von Seiten massiv mit riesigen Mengen von Objekten hantiert, und der Benutzer ist immer ungeduldig.

    Der Punkt mit dem Akkuverbrauch ist da auch durchaus nicht von der Hand zu weisen, wenn der Anteil des Overheads eben nicht mehr nur 2% ist, sondern gegebenenfalls 20% oder noch mehr.

    Ich persönlich komme eher von der Seite des massiven Numbercrunchings in C++ mit Millionen von verschachtelten Objekten und bin auch deshalb zumindest vom Konzept von Swift angetan, weil es eben zumindest grundsätzlich ähnliche Möglichkeiten bieten sollte wie C++.

    Gleichzeitig weiß ich aber genug über Objective-C, um andererseits aber auch wertzuschätzen, daß es dort eben die diversen statischen Einschränkungen so nicht gibt, mit denen man in C++ gelegentlich zu kämpfen hat, sondern dafür ganz andere Pattern und Möglichkeiten des Arbeitens mit Klassen und Objekten. Und deshalb ist es eben auch wichtig, daß Swift gleichzeitig auch mit Runtime-Objekten hantieren kann, und das in ein und derselben Syntax (während ja selbst Objective-C schon eigentlich zwei separate und sehr verschiedene Syntaxen und Semantiken vereinigt: C und Objective-C).

    Compiler-orientiertes Programmieren und Runtime-orientiertes Programmieren unterscheiden sich ziemlich; Aber beide haben ihre jeweiligen Vorteile (und Nachteile). Wenn Apple hier aufpaßt, können sie die Vorteile beider miteinander vereinen. Und was ich bisher gesehen habe sieht zumindest vielversprechend aus.
  • RegExpressive schrieb:

    Ich persönlich komme eher von der Seite des massiven Numbercrunchings in C++ mit Millionen von verschachtelten Objekten und bin auch deshalb zumindest vom Konzept von Swift angetan, weil es eben zumindest grundsätzlich ähnliche Möglichkeiten bieten sollte wie C++.

    Naja, aber mein Code (auch mehr oder weniger in die Richtung "numbercrunching") sollte schon Cross-Plattform sein, damit es z.B. auch auf einem Cluster läuft bzw. für viele Anwendungen MacOS einfach keine Option ist. Von daher ist Swift für mich genauso uninteressant wie Objective-C oder Visual Basic :) Objective-C kann ich immerhin relativ transparent mit C++ mischen, ich weiss gar nicht, wie das bei Swift auschauen soll...
    C++
  • Amin Negm-Awad schrieb:

    Ich dachte der Sinn von AnyObject ist es, dass er sich auf mich verlässt. Wieder etwas gelernt.

    Ich habe auch kein einziges Objective-C-Element verwendet.


    Ich hatte in der Tat angenommen, daßAnyObject letztlich nur eine abstrakte Basisklasse aller Objekte ohne Komponenten oder Methoden wäre (das wäre eine Möglichkeit gewesen), aber tatsächlich hat Apple das eher in Deinem Sinn definiert, wie ich gerade nochmal nachgelesen habe: AnyObject ist offenbar ein Protokoll und unterdrückt tatsächlich die Prüfung auf Vorhandensein von Methoden, denn AnyObject ist offenbar gerade dazu da, um von Swift aus beliebige Runtime-Objekte anzusprechen, denn es dient gerade als Gegenstück zu id bei der Kombination mit Objective-C.

    Wenn man auf einem AnyObject allerdings eine nichtexistente Methode aufzurufen versucht, gibt es eine Exception (was in Swift generell den Abbruch der Applikation bedeutet), wenn man das nicht abfängt:

    Ein Methoden-Aufruf auf einem AnyObject ist offenbar optional – man kann also mit derselben Syntax wie bei anderen optionals in Swift den Fall abfangen, daß die Methode doch nicht existierte, und ansonsten im gleichen Zug das Ergebnis weiterverwenden.

    Siehe Kapitel id Compatibility in Using Swift with Cocoa and Objective-C.

    Interessante Konstruktion, macht aber für die Schnittstelle zwischen den Sprachen einen logischen Eindruck.
  • zerm schrieb:

    Naja, aber mein Code (auch mehr oder weniger in die Richtung "numbercrunching") sollte schon Cross-Plattform sein, damit es z.B. auch auf einem Cluster läuft bzw. für viele Anwendungen MacOS einfach keine Option ist. Von daher ist Swift für mich genauso uninteressant wie Objective-C oder Visual Basic :)


    Mein diesbezüglicher Code war auch unter Linux eingesetzt worden, und dafür ist Swift natürlich wirklich noch(?) keine Option (obwohl man mal schauen kann, ob es über LLVM vielleicht auch dort zumindest als Möglichkeit einsickert).

    Aber bei OS X-Apps (beide Systeme) kann es durchaus nützlich sein, daß man nicht gleich gezwungen ist, für die zeitkritischeren Teile auf eine andere Sprache auszuweichen (vorausgesetzt, der Swift-Optimizer erreicht mal ein entsprechendes Niveau).

    zerm schrieb:

    Objective-C kann ich immerhin relativ transparent mit C++ mischen, ich weiss gar nicht, wie das bei Swift auschauen soll...


    Konzeptionell könnte das eigentlich ganz gut gehen; Die Hauptfrage wäre dabei aber wohl, ob Apple entsprechende Bridging-Möglichkeiten in den Compiler einbaut. Bei Objective-C sind sie da wahrscheinlich motivierter, und angesichts der Sprachmächtigkeit von Swift und C++ wäre das schon einiges an Arbeit, gerade bezüglich speziellerer Sonderfälle.
  • RegExpressive schrieb:

    Amin Negm-Awad schrieb:

    Ich dachte der Sinn von AnyObject ist es, dass er sich auf mich verlässt. Wieder etwas gelernt.

    Ich habe auch kein einziges Objective-C-Element verwendet.


    Ich hatte in der Tat angenommen, daßAnyObject letztlich nur eine abstrakte Basisklasse aller Objekte ohne Komponenten oder Methoden wäre (das wäre eine Möglichkeit gewesen), aber tatsächlich hat Apple das eher in Deinem Sinn definiert, wie ich gerade nochmal nachgelesen habe: AnyObject ist offenbar ein Protokoll und unterdrückt tatsächlich die Prüfung auf Vorhandensein von Methoden, denn AnyObject ist offenbar gerade dazu da, um von Swift aus beliebige Runtime-Objekte anzusprechen, denn es dient gerade als Gegenstück zu id bei der Kombination mit Objective-C.

    Wenn man auf einem AnyObject allerdings eine nichtexistente Methode aufzurufen versucht, gibt es eine Exception (was in Swift generell den Abbruch der Applikation bedeutet), wenn man das nicht abfängt:

    Ein Methoden-Aufruf auf einem AnyObject ist offenbar optional – man kann also mit derselben Syntax wie bei anderen optionals in Swift den Fall abfangen, daß die Methode doch nicht existierte, und ansonsten im gleichen Zug das Ergebnis weiterverwenden.

    Siehe Kapitel id Compatibility in Using Swift with Cocoa and Objective-C.

    Interessante Konstruktion, macht aber für die Schnittstelle zwischen den Sprachen einen logischen Eindruck.
    Es ist eben so wie in Objective-C. Mutmaßlich hatte ich auch deshalb geschrieben, dass es dann ja eigentlich Objective-C sei.

    Daher benötige ich auch keinen weiterführenden Hinweis.
    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"?
  • RegExpressive schrieb:


    Wenn man Tausende oder Millionen von Objekten mit vielen Sub-Objekten in großen Transaktionen bearbeitet, kann der reine Overhead der Methoden-Aufrufe sonst schon deutlich zubuche schlagen.


    Wenn du so viele Methodenaufrufe von Methoden die fast nichts tun hast, hast du auch ein Problem mit den virtuellen Methoden von C++. Lustigerweise ist das Objective-C-Framework von iOS auf mobilen Plattformen ja sehr effizient, was Microsoft so zum Beispiel nicht hinbekommt.

    RegExpressive schrieb:


    Es ist ja kein reiner Zufall, daß selbst OS X im Kernel für das IOKit auf C++ setzt und nicht auf Objective-C,


    Da bist du schlecht informiert. Das IOKit ist so low-level, dass selbst die Runtime von C++ zu groß ist und ein Subset verwendet wird. Es gibt zum Beispiel keine Exceptions, Multiple inheritance oder Templates - alles Features die hier immer für C++ hervorgehoben werden.

    RegExpressive schrieb:


    und viele komplexere bzw. Numbercrunching-Software eben auch.


    Was C++ auf eine Stufe mit Fortran (LAPACK) stellt.

    OpenCL basiert auch auf C99. Schön. Und jetzt? Es ist doch die Frage ob Swift sich auf Apple-Plattformen gut macht, wer Cross-Plattform-Entwicklung betreibt ist im Moment sowieso auf andere Sprachen angewiesen.