Guten Tag,
viele denken immer: Ach in MTA, da brauche ich mit Sicherheit nicht auf die Performance zu achten.
Falsch.
Auch MTA birgt einige Optimierungen.
Schwerpunkt 1 - Events:
Nehmen wir folgenden Code:
local pickup = createPickup(1337.1, 4242.1, 13, 3, 370) --Jetpack
function pickupHandler(player)
if source == pickup then
givePedJetPack(player)
end
end
addEventHandler('onPickupHit', getRootElement(), pickupHandler)
Dieser Code wird bei jedem Aufruf eines Pickups ausgeführt. Egal ob es sich um unser Pickup handelt, oder ein anderes.
Wir sollten also den Eventhandler nur auf unser Pickup hören lassen und somit nur unsere Funktion aufrufen, wenn wirklich nur unser Pickup aufgerufen wird.
local pickup = createPickup(1337.1, 4242.1, 13, 3, 370) --Jetpack
function pickupHandler(player)
givePedJetPack(player)
end
addEventHandler('onPickupHit', pickup, pickupHandler)
Ich merke immer wieder, bei großen Scripts, wie z.B. MTA:RL, merkt man immer wieder, was solch eine kleine Optimierung bewirkt.
Schwerpunkt 2 - Dateispeicherung:
Viele Nutzer machen den Fehler und speichern alles was geht in XML oder im schlimmeren Falle sogar in Files ab.
MTA bietet zur Datenspeicherung:
- eine interne SQLite3 Datenbank
- ein sehr gutes MySQL Plugin (http://wiki.multitheftauto.com/index.php?title=Modules/MTA-MySQL)
SQL bietet eine schnellere Auswertung von großen Datenmengen. Als die Umstellung bei meinem Script von XML nach MySQL erfolgte, konnte ich die Performancesteigerung gerade so spüren.
Ein weiterer Fehler, der oft begangen wird ist, wir speichern jede Kleinigkeit sofort in die Datei.
Wenn wirklich auf Dateien oder XML-Dateien zurückgeriffen wird, legt euch ein Array und speichert dort alles. Erst beim ausloggen solltet ihr Änderungen speichern.
Schwerpunkt 3 - Timer mit getElementsByType
Obwohl getElementyByType bereits seit 1.0.0 für die Nutzung in Timern optimiert wurde, gibt es hier eine weitere simple Möglichkeit, auf getElementyByType zu verzichen und einen loop schneller durchzuführen.
Was passiert beim Aufruf von getElementsByType?
Der Server bzw. Client fragt intern nach der Liste der Elemente. Jetzt muss er aus dieser Liste erstmal eine LUA-Liste generieren. Das kostet Zeit!
Ein einfaches Beispiel wäre eine interne Liste in Lua anzulegen und diese einfach abzufragen:
g_playerTable = {}
_getElementsByType = getElementsByType
function getElementsByType(elementtype)
if elementtype == "player" then return g_playerTable
else return _getElementsByType(elementtype) end
end
function onPlayerJoinHandler()
table.insert(g_playerTable, source)
end
addEventHandler('onPlayerJoin', getRootElement(), onPlayerJoinHandler)
function onPlayerDisconnectHandler()
for i, player in ipairs(g_playerTable) do
if player == source then
table.remove(g_playerTable, i)
break
end
end
end
addEventHandler('onPlayerDisconnect', getRootElement(), onPlayerDisconnectHandler)
Alles anzeigen
Schwerpunkt 4 - Scripte
Dieser Punkt ist speziell für große Scripte. Es lohnt sich bei großen Scripten immer, die Scripte mit luac zu compilen.
Vorallem bei Clienten ist das hilfreich, denn dort muss der Client sich nicht erst noch mit dem compilen beschäftigen.
Schwerpunkt 5 - GUI
Viele Scripter machen es so:
Sie laden beim laden der Resource alle Möglichen GUI's. Braucht ein eingeloggter Spieler bspw. eine Registrationgui? Mit Sicherheit nicht.
Meine Lösung: Legt für jede GUI, die nicht immer geladen sein muss eine Funktion an. In dieser Funktion schreibt ihr ein if-Statement mit einer globalen Variable. Falls diese false, lasst ihr die GUI erstellen, falls true passiert nichts. Vergesst nicht die Variable nach dem erstellen auf true zu setzten um nicht unnötige viele GUI-Elemente gleicher Art zu erzeugen.
to be continued...