2016-12-22 2 views
3

Wie ich es verstehe, können Werttypen in swift leistungsfähiger sein, weil sie im Gegensatz zum Heap auf dem Stack gespeichert sind. Aber wenn Sie viele Aufrufe an DispatchQueue.sync oder DispatchQueue.async machen macht dies nicht die Vorteile von Werttypen stumm, weil Schließungen auf dem Heap gespeichert sind?Führt die parallele Programmierung in swift Wertoptimierungen aus?

Antwort

2

Wie ich es verstehe, können Werttypen in swift leistungsfähiger sein, weil sie im Gegensatz zum Heap auf dem Stack gespeichert sind.

Manchmal. Oft nicht. Zum Beispiel enthält String Heap-allokierten Speicher. Viele Werttypen verfügen über versteckten Heapspeicherplatz (das ist tatsächlich wirklich Common). Sie erhalten also möglicherweise nicht den Leistungszuwachs, den Sie für viele Typen erwarten, aber in vielen Fällen verlieren Sie ihn auch nicht durch Schließungen.

Bei den Werttypen handelt es sich um Verhalten, nicht um Leistung (und natürlich müssen Sie zwischen value types and value semantics unterscheiden, die unterschiedlich sind und Auswirkungen auf die Leistung haben können). Das Schöne an Werttypen und DispatchQueue ist, dass Sie nicht versehentlich einen Wert für mehrere Warteschlangen ändern, weil Sie wissen, dass Sie eine eigene unabhängige Kopie haben. Zu dem Zeitpunkt, zu dem Sie den Aufwand für die Verteilung an eine Warteschlange (die zwar optimiert, aber immer noch nicht billig ist) bezahlt haben, sind die zusätzlichen Kosten für das Kopieren des Werttyps wahrscheinlich nicht das Hauptproblem.

Meiner Erfahrung nach ist es sehr schwierig, über die Leistung von Swift nachzudenken, insbesondere aufgrund von Kopier-auf-Schreib-Optimierungen. Aber die Tatsache, dass scheinbare "Werttypen" versteckte interne Referenztypen haben können, macht auch die Performance-Analyse sehr schwierig. Sie müssen oft interne Details kennen und sich auf sie verlassen können, die sich ändern können. Um auch nur einen schnellen Überblick zu bekommen, sollten Sie unbedingt Understand Swift Performance (möglicherweise ein paar Mal) anschauen. Wenn Sie irgendwelche Performance-Intuitionen aus C++ mitbringen, müssen Sie fast alles für Swift wegwerfen. Es macht einfach so viele Dinge anders.

1

Ich vermute, dass Ihre Ansicht der Leistungsmetriken und Optimierung nicht vollständig mit dem Swift-Modell übereinstimmt.

Zuerst sieht es so aus, als ob Sie diesen Punkt richtig verstanden haben, aber im Allgemeinen sind die Begriffe "Stack-Allocated" und "Heap-Allocated" irreführend. Werttypen können Teil von Referenztypen sein und sich auf dem Heap befinden. Ebenso müssen Dinge, die vermutlich auf den Heap gehen, nicht wirklich auf den Heap gehen: Ein Objekt mit Referenzzählung, das nachweislich keine Referenzzählung benötigt, könnte auf dem Stack zugewiesen werden, ohne dass es jemand merkt. In anderen Sprachen wie C++ ist die preferred terminology "automatischer Speicher" ("Stack") und "dynamischer Speicher" ("Heap"). Natürlich hat Swift diese Konzepte nicht (es gibt nur Werttypen und Referenztypen), aber sie sind nützlich, um Leistungsmerkmale zu beschreiben.

Escaping Schließungen müssen dynamisch gespeichert werden, da ihre Lebensdauer nicht an einen Stapelrahmen gebunden werden kann. Der Leistungspreis, den Sie zahlen müssen, um eine Funktion aufzurufen, die eine fluchtende Schließung erfordert, ist jedoch unabhängig davon, wie viele Variablen erfasst werden müssen, einheitlich, da eine Schließung immer zugeordnet wird und die Schließung Speicher für beliebig viele Werte haben kann.

Mit anderen Worten, alle erfassten Werte-typisierten Objekte werden in einer einzigen dynamischen Zuordnung gruppiert, und die Leistungskosten für die Speicherzuweisung werden nicht mit dem von Ihnen angeforderten Betrag skaliert. Daher sollten Sie bedenken, dass (kleine) Geschwindigkeitskosten mit dem Entweichen von Schließungen verbunden sind, diese Kosten jedoch nicht mit der Anzahl der Werte, die der Abschluss erfasst, übereinstimmen. Abgesehen von diesen unvermeidbaren Vorlaufkosten sollte es bei Werttypen keine Leistungseinbußen geben.

Zusätzlich, wie Rob sagte, ist jeder nicht-triviale Werttyp (Strings, Arrays, Dictionaries, Sets, etc.) tatsächlich ein Wrapper für einen Referenztyp, so dass Value-Typen für diese Objekte eher einen semantischen Vorteil hatten Ein Leistungsvorteil für den Anfang.