Avatar billede niemi Nybegynder
19. juni 2009 - 00:41 Der er 7 kommentarer og
1 løsning

Er mit loop ok performance-wise eller kan det gøres bedre?

for (int x = 0; x < this.getWidth(); x++) {
for (int y = 0; y < this.getHeight(); y++) {
//Something goes here
}
}

Jeg har ikke megen JAVA erfaring eller anden programmeringsmæssig baggrund. Jeg skal snart til eksamen hvor jeg skal forklare et meget simpelt program der indeholder et par loops af denne type.

Spørgsmålet er om jeg kan opnå bedre performance (meget lidt eller blot teoretisk gælder også) ved at skrive loopet på en anden måde?

På forhånd mange tak.
Avatar billede niemi Nybegynder
19. juni 2009 - 00:46 #1
I tilfælde af at koden inde i loopet, der hvor jeg har skrevet //Something goes here, er relevant kommer den her:

pixel = getPixel(x, y);
if (Starter.desiredColorArray == Starter.redImagesArray & pixel.getRed() > pixel.getGreen() & pixel.getRed() > pixel.getBlue() )
    pixel.setRed(255);
else if (Starter.desiredColorArray == Starter.greenImagesArray & pixel.getGreen() > pixel.getRed() & pixel.getGreen() > pixel.getBlue() )
    pixel.setGreen(255);
else if (Starter.desiredColorArray == Starter.blueImagesArray & pixel.getBlue() > pixel.getRed() & pixel.getBlue() > pixel.getGreen() )
    pixel.setBlue(255);
Avatar billede jpvj Nybegynder
19. juni 2009 - 01:07 #2
Hejsa,

Uden at være kyndig udi hvorledes Java optimerer sin afvikling af bytekoden, slog det mig at det *kunne* koste lidt performance, hvis this.get....() skal evalueres for hvert loop. Kaldet af metoden get....() er ikke "gratis", så hvis ikke det er optimeret væk, vil du kunne spare lidt ved at lave følgende:

int Width = this.getWidth()
int Height = this.getHeight()

for (int x = 0; x < Width; x++) {
for (int y = 0; y < Height; y++) {
//Something goes here
}
}

Inde i løkken har du nogle kald til get....() - tilsvarende kunne du gemme dem i variable i starten af løkken:
int red = pixel.GetRed()
..

Jeg har ikke kodet Java siden 2003, og dengang kostede det altså en del at kalde metoder hele tiden for at læse værdier ud. Men der er jo sikkert sket en del siden dengang, så jeg tager forbehold for "gammel viden".

Mvh JP
Avatar billede thesurfer Nybegynder
19. juni 2009 - 01:09 #3
Du kan altid optimere dine for-loops, ved at bruge så mange konstanter som muligt..

Eksempel (jeg kender ikke helt syntaksen, så du skal måske rette lidt):


for (int x = 0, int w = this.getWidth(); x < w; x++) {
for (int y = 0, int h = this.getHeight(); y < h; y++) {
//Something goes here
}
}


eller



int x = 0;
int w = this.getWidth();
int y = 0;
ing h = this.getHeight();

for (x = 0; x < w; x++) {
for (y = 0; y < h; y++) {
//Something goes here
}
}
Avatar billede niemi Nybegynder
19. juni 2009 - 01:56 #4
Tak jpvj, tak thesurfer :)

jpvj du er et geni! Selvfølgeligt, det er klart. Men inden jeg sætter mig til at spille alt for smart ved eksamensbordet, skal jeg lige vide helt præcist hvorfor det er hurtigere.

Jeg forstår at hver eneste gang x++ og y++ køres (lad os sige at billedet er 500px * 375px, det er 187500 gange) skal computeren undersøge this (det aktuelle billede) og få bredde og højde. Da størrelsen altid er den samme er der ingen grund til at tjekke dette så forbandet mange gange og derfor spørger vi blot én enkelt gang for hvert billede ved at bruge den kode du foreslår.

Er jeg galt på den?

thesurfer, jeg kan godt se at du i eksempel 2 har gjort det samme som jpvj med at flytte this.getWidth(); og this.getHeight(); uden for loopet således at vi kun spørger om billedets bredde og højde en enkelt gang. Men hvad hjælper det at flytte int x = 0; og int y = 0; uden for loopet, hvordan kan det give noget performance-wise?


jeg forstår ikke hvad man opnår ved at angive x=0 og y=0 uden for loopet. Kan du gå lidt i detaljer her?
Avatar billede thesurfer Nybegynder
19. juni 2009 - 03:07 #5
Meningen var sådan set bare at illustrere, at ved at smide dem uden for loopen, defineres de kun 1 gang.

Men, ja, x og y behøver du ikke at smide ud.. bare de andre værdier.



PS:

Hvis du en eller anden dag skal udføre nogle beregninger, se hvor du kan spare..

Eksempel (meget simplificeret):

a = (2 + 2) * 2 + (2 + 2) / 2

her vil det være oplagt at sætte en variabel til "2 + 2" og bruge variablen:
b = 2 + 2
a = b * 2 + b / 2
Avatar billede niemi Nybegynder
19. juni 2009 - 03:50 #6
Super thesurfer, jeg kan følge dig. Kan jeg dele points i mellem jer? I svarer sådan set begge på spm. :)

Hvad siger i til at anvende && i stedet for & i mine if-sætninger?
Avatar billede niemi Nybegynder
19. juni 2009 - 20:40 #7
De gik til jpvj, han var den eneste der havde afgivet et "svar".

Tak alle.
Avatar billede arne_v Ekspert
23. juni 2009 - 04:28 #8
Det er meget svært at udtale sig generelt om hvordan JIT compileren optimerer.

Men et tilfældigt stykke test kode:

public class LoopFun {
    private final static int REP = 2000000000;
    public static void test1() {
        long t1 = System.currentTimeMillis();
        SomeData sd = new SomeData(REP);
        for(int i = 0; i < sd.getN(); i++) {
            sd.add();
        }
        if(sd.getSum() != sd.getN()) {
            throw new RuntimeException("Ooops");
        }
        long t2 = System.currentTimeMillis();
        System.out.println("Keep in: " + (t2 - t1));
    }
    public static void test2() {
        long t1 = System.currentTimeMillis();
        SomeData sd = new SomeData(REP);
        int n = sd.getN();
        for(int i = 0; i < n; i++) {
            sd.add();
        }
        if(sd.getSum() != sd.getN()) {
            throw new RuntimeException("Ooops");
        }
        long t2 = System.currentTimeMillis();
        System.out.println("Move out: " + (t2 - t1));
    }
    public static void main(String[] args) {
        test1();
        test2();
        test1();
        test2();
        test1();
        test2();
    }
}

class SomeData {
    private int n;
    private int sum;
    public SomeData(int n) {
        this.n = n;
        sum = 0;
    }
    public void add() {
        sum++;
    }
    public int getN() {
        return n;
    }
    public int getSum() {
        return sum;
    }
}
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)
Keep in: 20546
Move out: 9891
Keep in: 20234
Move out: 9891
Keep in: 20516
Move out: 9890
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Server VM (build 1.3.1-b24, mixed mode)
Keep in: 3813
Move out: 156
Keep in: 125
Move out: 234
Keep in: 3188
Move out: 156
java version "1.4.2_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
Java HotSpot(TM) Client VM (build 1.4.2_02-b03, mixed mode)
Keep in: 4625
Move out: 4453
Keep in: 3828
Move out: 3797
Keep in: 3797
Move out: 3813
java version "1.4.2_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
Java HotSpot(TM) Server VM (build 1.4.2_02-b03, mixed mode)
Keep in: 172
Move out: 188
Keep in: 156
Move out: 187
Keep in: 172
Move out: 157
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
Keep in: 5453
Move out: 5109
Keep in: 3797
Move out: 3812
Keep in: 3797
Move out: 3891
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Server VM (build 1.5.0-b64, mixed mode)
Keep in: 360
Move out: 172
Keep in: 250
Move out: 172
Keep in: 172
Move out: 172
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)
Keep in: 4360
Move out: 4422
Keep in: 4390
Move out: 4422
Keep in: 4375
Move out: 4406
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)
Keep in: 172
Move out: 171
Keep in: 188
Move out: 172
Keep in: 156
Move out: 172

antyder at fodelen ved at flytte metode kald ud af for loop forsvandt med Java 1.4 !

Endbidere er jeg meget skeptisk overfor hvorvidt det selv før 1.4 havde en praktisk betydning for ret mange programmer !!
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
Kurser inden for grundlæggende programmering

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