ActionScript 3
Optymalizacja wydajności
Szukaj…
Grafika wektorowa
Grafika oparta na wektorze jest reprezentowana przez mnóstwo danych, które muszą być obliczone przez CPU (punkty wektorowe, łuki, kolory itp.). Wszystko inne niż proste kształty z minimalnymi punktami i liniami prostymi pochłonie ogromne ilości zasobów procesora.
Istnieje flaga „Buforuj jako bitmapę”, którą można włączyć. Ta flaga przechowuje wynik rysowania DisplayObject opartego na wektorze dla znacznie szybszych przerysowań. Pułapką tego jest to, że jeśli do obiektu zostaną zastosowane jakieś transformacje, cała rzecz musi zostać przerysowana i ponownie buforowana. Może to być wolniejsze niż całkowite włączenie go, jeśli zastosowano transformacje klatka po klatce (obrót, skalowanie itp.).
Generalnie renderowanie grafiki za pomocą map bitowych jest znacznie wydajniejsze niż używanie grafiki wektorowej. Biblioteki takie jak flixel wykorzystują to do renderowania duszków na „kanwie” bez zmniejszania liczby klatek na sekundę.
Tekst
Renderowanie tekstu zużywa dużo procesora. Czcionki są renderowane w sposób podobny do grafiki wektorowej i zawierają wiele punktów wektorowych dla każdej postaci. Zmiana tekstu klatka po klatce obniży wydajność. Flaga „Buforuj jako mapę bitową” jest niezwykle przydatna, jeśli jest używana poprawnie, co oznacza, że musisz unikać:
- Często zmieniając tekst.
- Przekształcanie pola tekstowego (obracanie, skalowanie).
Proste techniki, takie jak zawijanie aktualizacji tekstu w instrukcji if
, zrobią zasadniczą różnicę:
if (currentScore !== oldScore) {
field.text = currentScore;
}
Tekst może być renderowany przy użyciu wygładzającego modułu renderującego wbudowanego we Flash lub przy użyciu „czcionek urządzeń”. Użycie „czcionek urządzenia” powoduje, że tekst jest renderowany znacznie szybciej, chociaż sprawia, że tekst wygląda na postrzępiony (alias). Ponadto czcionki urządzenia wymagają, aby użytkownik zainstalował czcionkę, lub tekst może „zniknąć” na komputerze użytkownika, chociaż wygląda dobrze na twoim.
field.embedFonts = false; // uses "device fonts"
Wektor i dla każdego vs tablice i dla
Użycie typu Vector.<T>
i for each
pętli jest bardziej wydajne niż w przypadku konwencjonalnej tablicy i for
pętli:
Dobry:
var list:Vector.<Sprite> = new <Sprite>[];
for each(var sprite:Sprite in list) {
sprite.x += 1;
}
Zły:
var list:Array = [];
for (var i:int = 0; i < list.length; i++) {
var sprite:Sprite = list[i];
sprite.x += 1;
}
Szybkie usuwanie elementów tablicy
Jeśli nie potrzebujesz, aby tablica była w określonej kolejności, mała sztuczka z pop()
zapewni Ci ogromny wzrost wydajności w porównaniu do splice()
.
Kiedy splice()
tablicę, indeks kolejnych elementów w tej tablicy musi zostać zmniejszony o 1. Ten proces może zająć dużo czasu, jeśli tablica jest duża, a usuwany obiekt znajduje się bliżej początku tej tablicy .
Jeśli nie przejmujesz się kolejnością elementów w tablicy, możesz zamiast tego zastąpić element, który chcesz usunąć, elementem, który pop()
z końca tablicy. W ten sposób indeksy wszystkich innych elementów w tablicy pozostają takie same, a proces nie pogarsza się wraz ze wzrostem długości tablicy.
Przykład:
function slowRemove(list:Array, item:*):void {
var index:int = list.indexOf(item);
if (index >= 0) list.splice(index, 1);
}
function fastRemove(list:Array, item:*):void {
var index:int = list.indexOf(item);
if (index >= 0) {
if (index === list.length - 1) list.pop();
else {
// Replace item to delete with last item.
list[index] = list.pop();
}
}
}
Wektory zamiast tablic
Flash Player 10 wprowadził ogólny typ listy Vector. <*>, Który był szybszy niż tablica. Nie jest to jednak do końca prawda. Tylko następujące typy Vector są szybsze niż odpowiedniki Array, ze względu na sposób ich implementacji we Flash Playerze.
-
Vector.<int>
- Wektor liczb całkowitych 32-bitowych -
Vector.<uint>
- Wektor 32-bitowych liczb całkowitych bez znaku -
Vector.<Double>
- Wektor pływaków 64-bitowych
We wszystkich innych przypadkach użycie tablicy będzie bardziej wydajne niż użycie wektorów dla wszystkich operacji (tworzenia, manipulacji itp.). Jeśli jednak chcesz „mocno wpisać” swój kod, możesz użyć wektorów pomimo spowolnienia. FlashDevelop ma składnię, która umożliwia rozwijanie rozwijanych kodów nawet w przypadku tablic za pomocą /*ObjectType*/Array
.
var wheels:Vector.<Wheel> // strongly typed, but slow
var wheels:/*Wheel*/Array // weakly typed, but faster
Ponowne użycie i łączenie grafiki
Tworzenie i konfigurowanie obiektów Sprite
i TextField
w czasie wykonywania może być kosztowne, jeśli tworzysz setki tysięcy takich obiektów w jednej ramce. Dlatego powszechną sztuczką jest „łączenie” tych obiektów do późniejszego ponownego wykorzystania. Pamiętaj, że staramy się nie tylko zoptymalizować czas tworzenia ( new Sprite()
), ale także konfigurację (ustawienie właściwości domyślnych).
Powiedzmy, że budowaliśmy składnik listy przy użyciu setek obiektów TextField. Gdy musisz utworzyć nowy obiekt, sprawdź, czy istniejącego obiektu można ponownie użyć.
var pool:Array = [];
if (pool.length > 0){
// reuse an existing TextField
var label = pool.pop();
}else{
// create a new TextField
label = new TextField();
// initialize your TextField over here
label.setDefaultTextFormat(...);
label.multiline = false;
label.selectable = false;
}
// add the TextField into the holder so it appears on-screen
// you will need to layout it and set its "text" and other stuff seperately
holder.addChild(label);
Później, gdy niszczysz komponent (lub usuwasz go z ekranu), pamiętaj, aby dodać nieużywane etykiety z powrotem do puli.
foreach (var label in allLabels){
label.parent.removeChild(label); // remove from parent Sprite
pool.push(label); // add to pool
}
W większości przypadków najlepiej jest utworzyć pulę dla każdego użycia zamiast puli globalnej. Wadą tworzenia globalnej puli jest konieczność ponownej inicjalizacji obiektu za każdym razem, aby pobrać go z puli, aby negować ustawienia wprowadzone przez inne funkcje. Jest to równie kosztowne i prawie w ogóle neguje wzrost wydajności korzystania z puli.