Optimalisering

Optimalisering

> LeekScript-veiledning

Her vil vi snakke om optimalisering, målet med optimalisering er å forbedre ytelsen til en algoritme. Generelt, når vi snakker om optimalisering, snakker vi om utførelsestid, målet er å redusere tiden som kreves for å utføre en rekke instruksjoner.

I LeekScript estimeres denne utførelsestiden med et tall: antall operasjoner som brukes av denne beregningen. Vi skal derfor snakke om visse god praksis og gode reflekser for å optimalisere et program, uansett språk, samt visse optimaliseringer som er mer spesifikke for LeekScript, og nært knyttet til måten operasjoner telles på.

Hvis du ikke allerede har gjort det, inviterer jeg deg til å lese artikkelen LeekScript Tutorial: Operations.

Gode reflekser

Hvis du for eksempel lagrer 500 operasjoner på en funksjon som bare kalles én gang, vil du bare lagre 500 operasjoner. (logikk) På den annen side kan en innsparing av en enkelt operasjon, på en funksjon som kalles i en løkke av løkke av sløyfe, redusere kostnadene ved operasjoner av flere titusenvis av operasjoner.

Som bringer meg til det andre punktet:

Halve arbeidet med å optimalisere en kode består ganske enkelt av å lete etter hvor operasjonene går (da må du rope høyt og be dem komme tilbake). Hva er dyrt i koden?

For det, ingen hemmelighet, vi skal måle!

I vårt arsenal gir LeekScript en funksjon som vil vise seg å være svært nyttig: getOperations. Denne funksjonen lar deg vite antall operasjoner brukt til nå i koden.

Eksempel på et enkelt verktøy for å måle kostnaden for en funksjon:

global __debug_operasjon; funksjon startOp(){ __debug_operation = getOperations(); } function stopOp(title){ let ops = getOperations()-__debug_operation - 3; debug("Operasjoner (" + tittel + "): " + ops); }

startOp(); stopOp("tom test"); // tom test: 0

startOp(); si("hei verden"); stopOp("hei verden"); // hei verden: 30

Vi kan dermed bekrefte at si koster 30 operasjoner, som meddelt av dokumentasjonen.

Det er mulig, og jeg anbefaler på det sterkeste at du lager verktøy for å måle andre ting i AI-en din, som antall anrop til en funksjon, samt dens gjennomsnittlige kostnad for eksempel, som bedre vil måle kostnadsutviklingen i AI-en din, og virkningen av visse optimaliseringer.

Siden Kompleksitet hjelper deg å forstå hvorfor en algoritme er dyr og hvordan du løser problemet. For å oppsummere veldig enkelt, foretrekker vi å unngå hekkende løkker mellom dem så langt det er mulig. Vi vil også forsøke å begrense størrelsen på løkkene våre, for eksempel ved å bla gjennom bare våre tilgjengelige celler i stedet for å bla gjennom alle cellene på kartet. Det er viktig å merke seg at en algoritme som har lavere kompleksitet vil bruke mye færre operasjoner for et stort nok antall elementer å behandle, tenk på det før du prøver å skrape små optimaliseringer!

Fjerner løkker som ikke vil endre seg

Tenk deg følgende kode:

la TP = getTP();

// skyt så mange ganger som mulig på fienden! for (var i = 0; i < floor(TP / getWeaponCost(getWeapon())); i++) { useWeapon(getNearestEnemy()); }

getNearestEnemy-funksjonen vil bli kalt ved hver iterasjon av loopen mens den alltid vil returnere det samme resultatet! For å unngå dette, sett bare resultatet i en variabel før funksjonen. Vi gjør det samme for floor(TP / getWeaponCost(getWeapon())) som også blir evaluert ved hver iterasjon. Som gir:

la TP = getTP();

// skyt så mange ganger som mulig på fienden! var enemy = getNearestEnemy(); var nbShots = floor(TP / getWeaponCost(getWeapon())); // antall mulige skudd med gjeldende våpen for (var i = 0; i < nbShots; i++) { brukVåpen(fiende); }

Leek Wars-funksjoner som er dyre

inArray, inArray er praktisk, det gjør det vi vil, men det innebærer en betydelig kostnad i operasjoner som vi ikke nødvendigvis legger merke til ved første øyekast. Faktisk ser det slik ut inni:

function inArray(element, array){ for (var-verdi i matrise) if (verdi == vare) return true; returner falsk; }

Dette eksemplet er en god illustrasjon for å snakke om litt kompleksitet. Vi ser her at den reelle kostnaden for denne funksjonen i verste fall avhenger av størrelsen på array-arrayen, som vi vil kalle n*. Denne funksjonen har derfor en kompleksitet *n, det er den