Wie kann Swift in diesen Vergleichen so viel schneller sein als Objective-C?


115

Apple hat auf der WWDC14 seine neue Programmiersprache Swift vorgestellt . In der Präsentation wurden einige Leistungsvergleiche zwischen Objective-C und Python durchgeführt. Das Folgende ist ein Bild von einer ihrer Folien, von einem Vergleich dieser drei Sprachen, die eine komplexe Objektsortierung durchführen:

Bildbeschreibung hier eingeben

Es gab ein noch unglaublicheres Diagramm über einen Leistungsvergleich unter Verwendung des RC4- Verschlüsselungsalgorithmus.

Offensichtlich ist dies ein Marketinggespräch, und sie gingen nicht im Detail darauf ein, wie dies in jedem umgesetzt wurde. Ich frage mich allerdings:

  1. Wie kann eine neue Programmiersprache so viel schneller sein?
  2. Werden die Objective-C-Ergebnisse von einem fehlerhaften Compiler verursacht oder ist in Objective-C etwas weniger effizient als in Swift?
  3. Wie würden Sie eine 40% ige Leistungssteigerung erklären? Ich verstehe, dass die Speicherbereinigung / automatische Referenzkontrolle zusätzlichen Aufwand verursachen kann, aber so viel?

13
@MathewFoscarini Obj-C geht an Assembler, aber es hat einen teuren Mechanismus zum Versenden von Objektnachrichten. Für die meisten GUI-Arbeiten spielt das keine Rolle, aber für das Sortieren ist es sehr wichtig.
Donal Fellows

17
Der Vergleich zu Python ist hier der wahre Kratzer.
Asthasr

9
@syrion Marketing, und die Sprache scheint sich an der Syntax von Python zu orientieren (ähnlich wie bei Golang). Sie versuchen zu sagen: "Hey, Python-Entwickler, Sie können auf dem Mac etwas schreiben, das nicht zu fremd ist, und es muss SO viel schneller sein, sogar schneller als Objective C, von dem Sie nie den

4
@MichaelT Ich verstehe das, aber es ist immer noch seltsam. Jeder, der sich mit Sprachen auskennt, wird feststellen, dass Python als interpretierte Sprache (für die meisten Aufgaben) einfach nicht im gleichen Status wie Objective-C oder andere kompilierte Sprachen sein wird. Es ist merkwürdig, es als Benchmark zu verwenden.
Asthasr

7
Sie bedeuten wahrscheinlich die Zeit, die zum Schreiben des Codes benötigt wird ...
Lukas Eder

Antworten:


62

Erstens ist (IMO) ein Vergleich mit Python nahezu bedeutungslos. Nur der Vergleich mit Objective-C ist sinnvoll.

  • Wie kann eine neue Programmiersprache so viel schneller sein?

Objective-C ist eine langsame Sprache. (Nur C ist schnell, aber das liegt daran, dass es C ist.) Es war noch nie extrem schnell. Es war gerade schnell genug für ihren (Apples) Zweck und schneller als ihre älteren Versionen. Und es war langsam, weil ...

  • Entsteht Objective-C aus einem fehlerhaften Compiler oder ist Objective-C weniger effizient als Swift?

Objective-C garantierte, dass jede Methode dynamisch versendet wurde. Kein statischer Versand. Das machte es unmöglich, ein Objective-C-Programm weiter zu optimieren. Nun, vielleicht kann JIT-Technologie eine Hilfe sein, aber AFAIK, Apple hasst wirklich unvorhersehbare Leistungsmerkmale und Objektlebensdauer. Ich glaube nicht, dass sie irgendwelche JIT-Sachen übernommen hatten. Swift hat keine solche Garantie für den dynamischen Versand, es sei denn, Sie legen ein spezielles Attribut für die Objective-C-Kompatibilität fest.

  • Wie würden Sie eine 40% ige Leistungssteigerung erklären? Ich verstehe, dass die Speicherbereinigung / automatische Referenzkontrolle zusätzlichen Aufwand verursachen kann, aber so viel?

GC oder RC spielt hier keine Rolle. Swift beschäftigt ebenfalls hauptsächlich RC. Kein GC ist da und wird es auch nicht, es sei denn, es gibt einen großen architektonischen Sprung in der GC-Technologie. (IMO, es ist für immer) Ich glaube, Swift hat viel mehr Raum für statische Optimierung. Insbesondere Verschlüsselungsalgorithmen auf niedriger Ebene, die normalerweise auf umfangreichen numerischen Berechnungen beruhen, sind für statisch versandte Sprachen von großem Vorteil.

Eigentlich war ich überrascht, weil 40% zu klein scheinen. Ich habe viel mehr erwartet. Auf jeden Fall ist dies die erste Veröffentlichung, und ich denke, die Optimierung war nicht das Hauptanliegen. Swift ist noch nicht einmal komplett! Sie werden es besser machen.

Aktualisieren

Einige nerven mich, wenn sie behaupten, dass die GC-Technologie überlegen ist. Die folgenden Dinge können zwar strittig sein und sind nur meine voreingenommene Meinung, aber ich denke, ich muss sagen, um dieses unnötige Argument zu vermeiden.

Ich weiß, was konservative / Rückverfolgungs- / generationsbezogene / inkrementelle / parallele / Echtzeit-GCs sind und wie sie sich unterscheiden. Ich denke, die meisten Leser wissen das auch schon. Ich stimme auch zu, dass GC in einigen Bereichen sehr gut ist und in einigen Fällen auch einen hohen Durchsatz aufweist.

Ich vermute jedenfalls, dass die Behauptung des GC-Durchsatzes immer besser ist als die von RC. Der größte Teil des RC-Overheads stammt aus dem Nachzählen und Sperren, um die Variable für die Nachzählungsnummer zu schützen. Und die RC-Implementierung bietet normalerweise eine Möglichkeit, Zählvorgänge zu vermeiden. In Objective-C gibt es __unsafe_unretainedund in Swift (obwohl es für mich immer noch etwas unklar ist) unownedDinge. Wenn die Kosten für die Nachzählung nicht akzeptabel sind, können Sie versuchen, sie mithilfe der Mechanik selektiv zu deaktivieren. Theoretisch können wir ein fast einzigartiges Besitzerszenario simulieren, indem wir nicht beibehaltene Referenzen sehr aggressiv verwenden, um einen RC-Overhead zu vermeiden. Außerdem erwarte ich, dass der Compiler einige offensichtlich unnötige RC-Operationen automatisch eliminieren kann.

Anders als beim RC-System AFAIK ist das teilweise Deaktivieren von Referenztypen beim GC-System keine Option.

Ich weiß, dass es viele veröffentlichte Grafiken und Spiele gibt, die ein GC-basiertes System verwenden, und ich weiß auch, dass die meisten von ihnen unter mangelndem Determinismus leiden. Nicht nur für Leistungsmerkmale, sondern auch für die Verwaltung der Objektlebensdauer. Unity wird hauptsächlich in C ++ geschrieben, aber der winzige C # -Teil verursacht alle merkwürdigen Leistungsprobleme. HTML-Hybrid-Apps und immer noch von unvorhersehbaren Spitzen auf jedem System betroffen. Weit verbreitet bedeutet nicht, dass das überlegen ist. Es bedeutet nur, dass dies für Menschen, die nicht viele Möglichkeiten haben, einfach und beliebt ist.

Update 2

Um unnötige Auseinandersetzungen oder Diskussionen zu vermeiden, füge ich noch einige Details hinzu.

@Asik lieferte eine interessante Meinung zu GC-Spikes. Das heißt, wir können Value-Type-Anywhere- Ansätze als eine Möglichkeit betrachten, GC-Inhalte zu deaktivieren. Dies ist sehr attraktiv und auf einigen Systemen sogar möglich (zum Beispiel rein funktionaler Ansatz). Ich stimme zu, dass dies theoretisch nett ist. In der Praxis gibt es jedoch mehrere Probleme. Das größte Problem ist, dass die teilweise Anwendung dieses Tricks keine echten spitzenfreien Eigenschaften bietet.

Weil Latenzprobleme immer alles oder nichts sind . Wenn Sie 10 Sekunden lang einen Frame-Spike haben (= 600 Frames), fällt offensichtlich das gesamte System aus. Es geht nicht darum, wie besser oder schlechter. Es ist nur bestanden oder nicht bestanden. (oder weniger als 0,0001%) Wo ist dann die Quelle der GC-Spitze? Das ist eine schlechte Verteilung der GC-Last. Und das liegt daran, dass der GC grundsätzlich unbestimmt ist. Wenn Sie irgendeinen Müll machen, wird der GC aktiviert, und irgendwann kommt es zu einem Spike. Natürlich wird dies in der idealen Welt, in der die GC-Last immer ideal ist, nicht passieren, aber ich lebe in der realen Welt und nicht in der imaginären idealen Welt.

Wenn Sie Spitzen vermeiden möchten, müssen Sie alle Ref-Typen aus dem gesamten System entfernen . Aber es ist schwierig, verrückt und sogar unmöglich, da Teile wie das .NET-Kernsystem und die Bibliothek nicht entfernbar sind. Die Verwendung eines Nicht-GC-Systems ist weitaus einfacher .

Im Gegensatz zu GC ist RC grundsätzlich deterministisch, und Sie müssen diese verrückte Optimierung (nur für den Werttyp) nicht verwenden, nur um Spitzen zu vermeiden. Was Sie tun müssen, ist das Aufspüren und Optimieren des Teils, das die Spitze verursacht. In RC-Systemen ist Spike ein lokales Algorithmusproblem, in GC-Systemen sind Spikes jedoch immer ein globales Systemproblem.

Ich denke, meine Antwort ist zu weit vom Thema entfernt und besteht hauptsächlich aus der Wiederholung bestehender Diskussionen. Wenn Sie wirklich eine Überlegenheit / Unterlegenheit / Alternative oder irgendetwas anderes von GC / RC-Zeug behaupten möchten, gibt es auf dieser Site und in StackOverflow viele Diskussionen, und Sie können dort weiter kämpfen.


4
Die Speicherbereinigung, insbesondere von Generationen, ist in der Regel erheblich schneller als die Referenzzählung.
Jan Hudec

9
@JanHudec Ihre deutlich schnellere ist im Echtzeit-Grafikbereich einfach bedeutungslos. Deshalb erwähne ich, dass bei GC ein großer Sprung erforderlich ist. Generations-GC ist theoretisch und praktisch nicht annähernd spitzenfrei.
Eonil

5
Schneller und spitzenfrei sind völlig orthogonale Kategorien. Generationenmüllsammler sind schneller . Sie sind nicht spitzenfrei.
Jan Hudec

4
Was Sie sprechen, ist Durchsatz . Schneller war schon immer ein vager Begriff und kann durch den Kontext alles bedeuten. Wenn Sie sich über die Bedeutung von Begriffen streiten möchten, sollten Sie einen genaueren Begriff verwenden als einen schnelleren, insbesondere unter Berücksichtigung der aktuellen Kontextgrafiken in Echtzeit.
Eonil

11
@JanHudec: Auf Mobilgeräten oder auf Geräten mit eingeschränkten Ressourcen ist die GC nicht wesentlich schneller und ist in der Tat ein wesentlicher Teil des Problems.
Mason Wheeler

72

Die Sprache ist 3,9-mal schneller als Python und verliert durchweg die meisten Benchmarks.

Das Benchmarks-Spiel zeigt C ++ - Programme, die in den meisten Fällen um eine Größenordnung schneller sind als Python-Programme. Im Vergleich zu Java, C # (auf Mono), OCaml, Haskell und sogar Clojure, die nicht statisch typisiert sind, ist es nicht viel besser.

Die eigentliche Frage ist also, wie ist Objective-C nur 2,8-mal schneller als Python. Anscheinend wählten sie sorgfältig den Benchmark, bei dem der langsame, voll dynamische Versand von ObjC sehr weh tut. Jede statisch typisierte Sprache sollte es besser können. Bei der komplexen Objektsortierung gibt es viele Methodenaufrufe zum Vergleichen der Objekte, und der tatsächliche Vergleich selbst war wahrscheinlich nicht sehr komplex. Wenn Swift also die Typinformationen zumindest teilweise nutzt, kann es die Methodenaufrufe leicht verbessern, und es gibt nicht genügend andere Operationen, in denen ObjC besser sein könnte.

Wie das Benchmark-Spiel deutlich zeigt, ist die relative Leistung bei verschiedenen Aufgaben natürlich sehr unterschiedlich, so dass ein Benchmark nicht wirklich repräsentativ ist. Wenn sie einen Benchmark hätten, bei dem es einen größeren Vorteil hätte, hätten sie uns stattdessen diesen gezeigt, also ist es bei anderen Aufgaben wahrscheinlich nicht besser oder nicht so viel.


13
Ich verstehe den Sinn dieser Antwort nicht ganz. Beantworten Sie "wie schnell ist schneller" mit "die Benchmarks sind fehlerhaft"? Ist das der Punkt, den Sie machen? Ich verstehe nicht, wie das beantwortet, was gefragt wurde.
Bryan Oakley

15
@BryanOakley: Ich denke nicht, dass die Benchmarks fehlerhaft sind, aber die Möglichkeit, dass sie den einen Benchmark ausgewählt haben, bei dem Swift schneller war, muss mit Sicherheit in Betracht gezogen werden.
Jan Hudec

23
Es ist möglich, dass die Antwort auf "Wie ist Swift schneller?" könnte sein "Es ist eigentlich nicht", @BryanOakley; Das ist der Kern, den ich aus Jan's Antwort bekomme. "Lügen, verdammte Lügen und Statistiken" schließlich.
Josh Caswell

4
Vor einer Weile gebenchmarkt wir Codename One auf iOS laufen und unsere Java - Implementierung war viel schneller als Objective-C codenameone.com/blog/... Jan richtig, dynamische Dispatch ist wirklich langsam, wenn sie sie sogar ein wenig dann einige Benchmarks verbessert werden zeigen eine enorme Verbesserung. Wenn sie ARC sogar um einen Bruchteil verbessern (dank einer besseren Code-Analyse), können sie eine lächerliche Menge an Komplexität loswerden. Je eingeschränkter die Sprache, desto mehr Möglichkeiten kann der Compiler zur Optimierung nutzen (siehe Java) und Swift fügt Einschränkungen hinzu.
Shai Almog

7
Die Antwort von Jan ist eine perfekte Antwort auf das erste und wahrscheinlich das zweite Quartal. Als ich die Benchmarks eines Marketingereignisses als Keynote sah, dachte ich: "Wow, nur 1,3x im ausgewählten Best-Case. Was werden wir mit dem durchschnittlichen Ergebnis? 0,3x?"
Amin Negm-Awad,

5

Objective-C löst jeden Methodenaufruf dynamisch aus.

Hypothese: Der Benchmark verwendet statische Typisierung, damit der Swift-Compiler die compareMethodensuche aus der sortSchleife herausholt. Dies erfordert eine enge Typeinschränkung, die nur komplexe Objekte im Array zulässt, keine Unterklassen von Complex.

(In Objective-C können Sie die Methodensuche manuell starten, wenn Sie dies wirklich möchten. Rufen Sie dazu die Sprachlaufzeitunterstützung auf, um den Methodenzeiger nachzuschlagen. Stellen Sie sicher, dass alle Instanzen im Array derselben Klasse angehören .)

Hypothese: Swift optimiert die Referenzzählung von Anrufen außerhalb der Schleife.

Hypothese: Der Swift-Benchmark verwendet eine komplexe Struktur anstelle eines Objective-C-Objekts, sodass Sortiervergleiche weder dynamische Methodenversendungen (da keine Unterklassen möglich sind) noch Referenzzählarbeiten (da es sich um einen Werttyp handelt) erfordern.

(In Objective-C können Sie für die Leistung auf C / C ++ zurückgreifen, sofern es sich nicht um Objective-C-Objekte handelt, z. B. um das Sortieren eines C-Arrays von Strukturen.)


3

Ehrlich gesagt, wenn sie die Quelle nicht für die von ihnen verwendeten Tests freigeben, würde ich nichts vertrauen, was Apple zu diesem Thema zu sagen hat. Denken Sie daran, dies ist das Unternehmen, das aus Stromgründen von PPC zu Intel gewechselt ist, als 6 Monate zuvor behauptet wurde, Intel habe den Intel-Hasen in einem Werbespot gelutscht und tatsächlich angezündet. Ich würde gerne einen unwiderlegbaren Beweis dafür sehen, dass Swift in mehr Kategorien schneller als ObjC ist als nur beim Sortieren.

Außerdem müssen Sie alle Statistiken, die bei WWDC veröffentlicht werden, in Frage stellen, da sie den Geruch von Marketing überall auf sich wirken lassen.

Abgesehen davon habe ich selbst keine Tests zwischen swift und ObjC durchgeführt, aber meines Wissens hat swift seine eigenen LLVM-IR-Erweiterungen und es ist möglich, dass zur Kompilierungszeit mehr Optimierungen durchgeführt werden als in ObjC.

Vollständige Offenlegung: Ich schreibe einen Open-Source-Swift-Compiler unter https://ind.ie/phoenix/

Wenn jemand mithelfen möchte, sicherzustellen, dass Swift nicht nur auf Apple-Hardware verfügbar ist, lassen Sie es mich wissen, und ich würde Sie gerne einbeziehen.


2
Das liest sich eher wie ein Garantiekommentar, siehe Wie man
Mücke

2
Ist es jetzt besser? :)
greg.casamento

0

Ich habe mich durch das Swift-Tutorial gekämpft, und es scheint mir, dass Swift bodenständiger ist (ich denke an Visual Basic), mit weniger 'Objektifizierung' als Objective-C. Hätten sie C oder C ++ berücksichtigt, hätte letzteres vermutlich gewonnen, da sie nur noch mehr Kompilierungszeit haben.

In diesem Fall gehe ich davon aus, dass Objective-C das Opfer der objektorientierten Reinheit (und des Overheads) ist.


13
In einer Sprache wie C, die keine systemeigene Implementierung von Objekten hat, wäre es etwas schwierig, einen Benchmark für die Sortierung komplexer Objekte durchzuführen. Da das Publikum für diesen Vortrag wahrscheinlich zu 100% aus Objective-C-Programmierern bestand, ist ein Vergleich mit einer Sprache wie C ++ auch nicht sehr sinnvoll. Der springende Punkt ist nicht "hey, das ist die beste Sprache, die es je gab!" sondern "hey, das ist schneller als die Sprache, die Sie jetzt für die OSX / iOS-Entwicklung verwenden".
Bryan Oakley

10
C hat eine sehr gute Qualität, qsortdie eine komplexe Objektsortierung ermöglicht. Es wird nur ein Rückruf verwendet, der die vorhandenen Objekte versteht. Ich vermute, C ++ fehlt, weil std::sortes Swift in Verlegenheit bringen würde. (Da es sich um eine Vorlage handelt, kann ein C ++ - Compiler diese stark optimieren, bis die Schleife wieder
freigegeben wird

@MSalters: Da stimme ich Ihnen voll zu. Sowohl C als auch C ++ können Swift hinter sich lassen. Wäre es möglich, den durchgeführten Test zu bekommen. Ich bin mehr als bereit, den gleichen Benchmark mit Swift, Objective-C, C ++ und C durchzuführen.
Painted Black

@ BryanOakley auch, "Diese Sprache erfordert weniger eckige Klammern!"
Nick Bedford

1
Diese Antwort enthält kein Wasser und ist fürchterlich irreführend. OO ist nicht sehr langsam. Tatsächlich werden die schnellsten Systeme C ++, Java und C # sein, und der Programmierstil (stark OO oder nicht) hat nur sehr wenig mit den resultierenden Geschwindigkeiten zu tun, es sei denn, Sie haben wirklich schlechter Code.
Bill K
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.