2013-07-11 15 views
8

Um die Leistung der Benutzeroberfläche zu verbessern, wählte der Präsentator 2011 in der WWDC-Videosession 121 die abgerundeten Ecken mit UIBezierPath in drawRect:, anstatt den Eckenradius direkt auf einer Ebene festzulegen.Zeichnet abgerundete Ecke in DrawRect: schneller als mit CALayer setCornerRadius?

Warum ist Zeichnen mit UIBezierPath unbedingt schneller? drawRect: passiert in Software, die auch langsam sein kann.

+0

ID möchte ich selbst wissen. –

+0

IMHO die Zeichnung passiert in Hardware, erstellt DrawRect die Display-Listen, die an die Hardware übergeben und dort gerendert werden – AlexWien

Antwort

22

Kurze Antwort: Wahrscheinlich bleiben Sie einfach mit CALayer cornerRadius, bis Sie ein Leistungsproblem sehen.

Lange Antwort:

Wir zunächst zwischen „Zeichnung“ und „Compositing“ unterscheiden müssen.

Zeichnen auf iOS ist der einfache Vorgang des Füllens einer Textur mit Pixeln (eine CPU eingeschränkte Aufgabe). Beim Compositing werden alle diese Texturen in einem einzigen Bild abgeflacht, um auf den Bildschirm gedruckt zu werden (eine GPU-beschränkte Aufgabe). Im Allgemeinen, wenn Sie scrollen oder animieren, besteuern Sie die GPU, was gut ist, weil Dinge, wie das Verschieben aller Pixel um eins, etwas sind, was die GPU zum Frühstück isst.

-drawRect: ist reine Zeichnung und verwendet die CPU, um eine Textur zu füllen. CALayers cornerRadius ist im Compositing-Schritt erledigt und betont die GPU.

Verwendung von -drawRect: hat sehr hohe Anfangskosten (es könnte leicht länger als ein Frame dauern) und nicht triviale Speicherauslastung, aber scrollt danach sehr glatt (es ist nur eine Textur wie jede andere Textur). Mit dem Eckenradius von CALayer können Sie blitzschnell eine Reihe von Ansichten mit Eckenradius erstellen, aber sobald Sie mehr als ein Dutzend bekommen, können Sie sich von der Scrollgeschwindigkeit verabschieden (denn die GPU muss nicht nur normale Scroll-Aufgaben erledigen, sondern muss auch) fügen Sie den Eckenradius wieder in Ihre Ansicht ein).

Aber nehmen Sie mein Wort dafür nicht, haben Sie etwas Mathe. Ich passte Florian Kugler’s benchmark an und lief auf einem iPhone 4S mit iOS 6.1.3. Ich messe, wie viele Ansichten anfänglich in 1/60 einer Sekunde erstellt werden können, und messe dann, wie viele Ansichten animiert werden können, bevor die Bildrate unter 60 fps fällt. Mit anderen Worten: Vorabkosten gegenüber Framerate-Kosten.

 
             | -drawRect:  | CALayer’s cornerRadus 
max number of views rendered in 16.6ms |  5 views |  110 views 
max number of views animating at 60fps | ~400 views |  12 views 

(beachten Sie, dass die App für die Verwendung von zu viel Speicher bei 500 -drawRect getötet wird: views)

Am Ende des Tages, in meinen eigenen Projekten neige ich dazu, so viel zu CALayer des corner haften wie möglich. Ich habe selten mehr als ein paar Ansichten mit abgerundeten Ecken und -drawRect benötigt: hat einfach zu viel von einer anfänglichen Leistung getroffen. Und eine Ansicht zu unterteilen, nur um die Ecken zu runden, ist nur, ugh.

Aber egal, welche Methode Sie am Ende wählen, achten Sie darauf, wie reibungslos und reaktionsschnell Ihre App ist, und reagieren Sie entsprechend.

+0

Danke für die beste Antwort. –

+0

Können Sie andere ähnliche Dinge kommentieren, z. B. Schatten, Masken, Textgröße und Rendering usw.? Werden diese Operationen auf der CPU oder der GPU ausgeführt, oder wann sollten Sie die Verwendung von drawRect: vs CALayer/UIKit-Eigenschaften in Betracht ziehen? –

+0

Der vorgenannte Post (http://floriankugler.com/blog/2013/5/24/layer-trees-vs-flat-drawing-graphics-performance-across-ios-device-generations) dreht sich alles um die Messung von DrawRect vs Standard Lagen. Sonst habe ich keine konkrete Rückmeldung außer Schatten.Es gibt einige Möglichkeiten, mit Schatten umzugehen (manuelles Zeichnen, CALayer Schatten, CALayer Schatten + Rasterisieren, CALayer Schatten + Schattenpfad) mit unterschiedlichen Leistungen: http://www.omnigroup.com/blog/entry/ipad_drop_shadow_performance_test – shusta

Verwandte Themen