Avatar billede larsdue Nybegynder
13. januar 2004 - 11:09 Der 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!)

/Lars
Avatar billede barklund Nybegynder
13. januar 2004 - 11:20 #1
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]);
        }
    }
};

Men optimeringen er nok ikke stor :)
Avatar billede larsdue Nybegynder
13. januar 2004 - 11:29 #2
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.

/Lars
Avatar billede barklund Nybegynder
13. januar 2004 - 11:37 #3
Stadig en lille smule optimeret...

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 :)
Avatar billede larsdue Nybegynder
13. januar 2004 - 11:42 #4
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!
Avatar billede barklund Nybegynder
13. januar 2004 - 12:06 #5
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?
Avatar billede larsdue Nybegynder
14. januar 2004 - 14:45 #6
Graferne skal i princippet køre på samme måde som Performance gør i Task Manager, bare i modsat retning/spejlvendt.
Avatar billede barklund Nybegynder
14. januar 2004 - 14:53 #7
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...
Avatar billede larsdue Nybegynder
14. januar 2004 - 15:05 #8
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?
Avatar billede barklund Nybegynder
14. januar 2004 - 15:33 #9
Ja gerne, selvom jeg nu aldrig helt har forstået det ;)
Avatar billede barklund Nybegynder
14. januar 2004 - 15:33 #10
*host*
Avatar billede larsdue Nybegynder
14. januar 2004 - 15:36 #11
Vi deler i porten :-)
Avatar billede larsdue Nybegynder
14. januar 2004 - 15:36 #12
*harg*
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester