13. januar 2004 - 11:09Der er
10 kommentarer og 2 løsninger
Optimering af funktion til at tegne graf - reducer CPU forbrug
Jeg arbejder på et display, som skal kunne vise et antal grafer med en opdaterings hastighed på 1 sec. Punkterne til hver graf ligger i et 2 dimensionelt array, hvor hvert punkt har 3 værdier: y-koordinaten, linie-tykkelsen og linie-farven. For at tegne grafen benytter jeg følgende funktion, som tager et 2 dim array, et x-interval, samt start x- og y-koordinater som indput.
drawCurve = function (tmpArray,tmpXInterval,tmpXCoordinate,tmpYCoordinate){ this.clear(); var x = tmpXCoordinate; var y = tmpYCoordinate; var init = true; for (var i=tmpArray.length-1; i>=0; i--) { if (init) { this.moveTo(x,y-tmpArray[i][0]); init = false; } this.lineStyle(tmpArray[i][1],tmpArray[i][2]); x=x+tmpXInterval; this.lineTo(x,y-tmpArray[i][0]); } }
Funktionen løber arrayet igennem bagfra, da jeg anvender .push til at tilføje nye målinger til arrayet. Samtidig skal grafen vises således at den nyeste værdi ligger på x=0 (i et koordinat system) og resten af målingerne skal så vises ud af x-aksen. Når en ny måling skal vises, skal de resterende målinger derfor flyttes et x-interval til højre!
Funktionen virker efter hensigten og grafen bliver tegnet korrekt. Problemet opstår først når mit array med målinger bliver meget stort eller når jeg forsøger at vise graferne for 20 arrays i det samme display. Når jeg forsøger dette, så har jeg et CPU forbrug på 100%, hvilket er uacceptabelt!
Hvordan kan jeg optimere min funktion til at håndtere de mange grafer? Hvad gør jeg forkert eller har overset? Kan man evt lave det på en anden måde?
En hurtig korrekt besvarelse, kan evt. udløse bonus point (I need a solution asap!)
I dette særtema ser vi på, hvordan cloud og AI bliver fundamentet for virksomhedernes digitale forretning, og hvordan de nye muligheder for automatisering og forretningsværdi kan udnyttes uden at miste overblik, sikkerhed og menneskelig kontrol.
Umiddelbart er der ikke meget at gøre - det vil jo altid være en grænse for, hvor meget flash kan gøre inden for acceptabel tid.
Dog tænker jeg lidt, hvorfor gemmer du for hvert linjestykke både tykkelse og farve - ændrer de to faktorer sig da hele tiden?
Jeg vil tro at følgende nok er det mest optimale:
drawCurve = function (a, i, dx, dy) { with (this) { clear(); moveTo(x = dx, dy - a[a.length - 1][0]); lineStyle(a[a.length][1], a[a.length][2]); var i = a.length; while (i--) { x += dx; lineTo(x, y - a[i][0]); } } };
Mht. linietykkelse og farve, så er det således, at f.eks. hvis en temperatur kommer over 500 grader, så skal grafen ændre udseende. F.eks. blive tykkere og vist i rødt. Problemer er, at disse grænse værdier ikke er fastsatte og kan variere. Dvs. leverandøren af målingerne skal kunne vælge disse, derfor nødvendigheden af at gemme tykkelse og farve for hvert punkt.
Hvis det ikke kan lade sig gøre at optimere på den metode jeg har valgt, så er alternativet en anden metode, som kan køre bedre. Jeg er åben for forslag.
drawCurve = function (a, i, dx, dy) { with (this) { clear(); moveTo(x = dx, dy - a[a.length - 1][0]); var i = a.length; while (i--) { lineStyle(a[i][1], a[i][2]); x += dx; lineTo(x, y - a[i][0]); } } };
Men skal det optimeres for alvor, så skal det tænkes forfra. Skal man virkelig have 20 grafer oveni hinanden? Hvis det er en meget stor graf, kan man så ikke kun vise hvert 3. eller 4. punkt? Og lignende optimeringer kan man putte ind rundt omkring...
Men ovenstående metode er jo måden at tegne det på - det kan du ikke gøre anderledes :)
Jeg pusler lidt med at tegne alle graferne ind i et movie klip, således at jeg hvert sekundt kun tegner 20 nye punkter et x-interval til venstre, for så umiddelbart bagefter at flytte hele movie klippet det tilsvarende x-interval til højre. Det giver samme visuelle effekt og er i mine forløbige tests ikke så CPU tungt. Problemer er nu bare hvor stort/langt et movie klip kan være, før det igen begynder at tvinge CPU/hukommelse i knæ og om man skal overveje en loop effekt, så man kun har et movie klip, der eks. er 1000 pixels langt!
Jeg forstår ikke helt hvad du vil. Du kan tegne utrolig meget og flytte det, men jeg forstår ikke helt. Er det en konstant graf, der hele tiden skalerer derudaf og får nye tal ind eller hvordan? Hvorfor kan du ikke bare fjerne det, som man har set og som er scrollet uden for skærmen?
oh, jamen så burde det da være forholdsvist nemt... bare at tegne en streg på og så flytte movieclippet onEnterFrame(?)... og måske endda lægger hver streg i hver sit movieclip - så kan du fjerne dem igen...
Ja, det er også det jeg er nået frem til. Pt. tegner jeg i det samme movieclip og flytter så dette. Metoden med at placere hver streg/punkt i sit eget movieclip æder for meget CPU.
Nå, men så kan vi jo godt lukke dette spørgsmål. Vil du have en slat point for din rådgivning barklund?
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.