Zeichnet eine abgerundete Ecke in drawRect: schneller als mit CALayer setCornerRadius?

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 zu setzen.

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

    
Evil Nodoer 11.07.2013, 19:14
quelle

1 Antwort

22

Kurze Antwort: Bleib einfach bei CALayers cornerRadius, bis du ein Performance-Problem siehst.

Lange Antwort:

Zunächst müssen wir zwischen "Zeichnen" und "Compositing" unterscheiden.

Das Zeichnen auf iOS ist die einfache Aufgabe, eine Textur mit Pixeln zu füllen (eine CPU-beschrä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 reines Zeichnen und verwendet die CPU zum Füllen einer Textur. CALayers cornerRadius ist im Compositing-Schritt erledigt und betont die GPU.

Die 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 flüssig (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 Mathematik. Ich habe Florian Kuglers Benchmark 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.

%Vor%

(Beachten Sie, dass die App für die Verwendung von zu viel Arbeitsspeicher bei 500-drawRect: views beendet wird)

Am Ende des Tages bleibe ich bei meinen eigenen Projekten so weit wie möglich bei CALayers cornerRadius. 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 letztendlich wählen, stellen Sie sicher, dass Sie messen und darauf achten, wie reibungslos und reaktionsschnell Ihre App ist und reagieren Sie entsprechend.

    
shusta 11.07.2013, 20:52
quelle

Tags und Links