Avatar billede michael_g Nybegynder
10. september 2004 - 00:54 Der er 10 kommentarer og
1 løsning

Meget langsom for-løkke - kan man gøre noget?

Jeg har denne kode som "køre" et bitmap igennem og laver det om til gråtoner, mit problem er at jeg ikke kan forstå hvorfor C# er meget længere tid om det end f.eks Delphi

på min computer som er en 1.7 Ghz P4 tager det omkring et til to sekunder!!! Delphi gør det inden jeg kan nå at blinke en eneste gang... (Bmp’et er ca. 300 x 400 pixel)

Er der nogen der kan forklare mig om jeg gør noget forkert, eller kan gøre noget for at gøre den væsentlig hurtigere? Mit problem er at jeg skal køre ret mange bitmap igennem med mange løkker og det tager bunke tid...

Her er et eksempel på en af de mange løkker jeg bruger i mit program

public static Bitmap ConvertToGreyscale(Bitmap Bmp)
{
  Bitmap Bmp1 = new Bitmap(Bmp.Width, Bmp.Height);
  Color PixelColor;
  for (int PixelY = 1; PixelY <= Bmp.Height-1; PixelY++)
  {
    for (int PixelX = 1; PixelX <= Bmp.Width-1; PixelX++)
    {
      PixelColor = Bmp.GetPixel(PixelX, PixelY);
      int Grey = (PixelColor.R + PixelColor.G + PixelColor.B)/3;
      Bmp1.SetPixel(PixelX, PixelY, Color.FromArgb(Grey, Grey, Grey));
    }
}
return Bmp1;
}
Avatar billede pfp Nybegynder
10. september 2004 - 00:57 #1
Ikke at jeg tror det har den store betydning, men der er vel ingen grund til at du definerer int grey inde i din for løkke? Den kunne vel lige så godt defineres uden for og dermed undgå at blive defineret for hver eneste pixel?
Avatar billede michael_g Nybegynder
10. september 2004 - 01:16 #2
Nu har jeg lige ændret i koden alle de steder hvor jeg har defineret variabler inde i løkken, men jeg kan desværre ikke mærke nogen forskel.
Avatar billede pfp Nybegynder
10. september 2004 - 01:18 #3
Nej tænkte jeg nok, men syntes bare alligevel det var værd at forsøge det.
Avatar billede finger Nybegynder
10. september 2004 - 08:34 #4
Jeg tror (og nu gætter jeg bare :)) simpelthen at det går så langsomt fordi du skal igennem løkken mange gange. Hvilket billede tester du på? et billede på fx 1280x1024 indeholder jo over 1,3 milloner pixels. Dvs at du komme igennem løkken 1,3 milloner gange. Det tager jo noget tid....
Alternativt kan det være at de metoder du bruger (fx BitMap.SetPixel) i sig selv er en "langsom" metode.
Mon ikke der findes nogle metoder som kan sætte gamma eller farveskala generelt?
Avatar billede dsj Nybegynder
10. september 2004 - 09:00 #5
At initialisere variable udenfor løkken, i stedet for inden i den, burde ikke gøre nogen forskel. Moderne compilere, i hvert fald i Java-verdenen, ser den slags ting, og sørger selv for at optimere ved kun at allokere hukommelsen én gang for hele løkken. Det skulle undre mig meget, om ikke Microsoft har tænkt over det samme :-)
Avatar billede arne_v Ekspert
10. september 2004 - 09:29 #6
300x400 er kuen 120000 (og 120000 gennemløb tager ingen tid på en moderne CPU).

Jeg er helt overbevist om at forskellen mellem C# og Delphi ligger i metode
kaldene (GetPixel, SetPixel).

Det betyder intet om den int er indenfor eller udenfor løkken.

Hvis du skulle prøve noget så skulle du lave en GreyColor struktur udenfor
løkken og sætte værdier i den fremfor at konstruere en ny med FromArgb.

Men det tror jeg heller ikke betyder noget.

Hvis det var løkke overhead som var problemet så skulle vi til at kigge
på loop unrolling, men formentlig gør .NET det af sig selv. Og det er ikke
løkke overhead som er problemet.
Avatar billede vaco Nybegynder
10. september 2004 - 09:47 #7
Måske er det hurtigere hvis du benytter pointere:

BitmapData data = _bitmap.LockBits(
new Rectangle(0, 0, _bitmap.Width, _bitmap.Height), ImageLockMode.ReadWrite,
PixelFormat.Format24bppRgb);
if (data != null)
{
    unsafe
    {
    byte * p = (byte *)data.Scan0.ToPointer();

    for (int y = 0; y < data.Height; y++)
    {
        for (int c = 0; c < data.Stride; c += 3)
        {
        // GET RGB
        byte b = p[c];
        byte g = p[c+1];
        byte r = p[c+2];

        // Set pixel to
        p[c] = din farve;
        p[c+1] = din farve;
        p[c+2] = din farve;
        }
        p += data.Stride;
    }
    }
}
Avatar billede vaco Nybegynder
11. september 2004 - 18:55 #8
Lever dette spg. stadig... blev problemet løst?
Avatar billede michael_g Nybegynder
13. september 2004 - 05:57 #9
Jeg kan glædeligt meddele jer at jeg har siddet op hele natten og skrevet alle mine mange løkker om og nu virker det endeligt og det er blevet MEGET hurtigere mange tak for hjælpen, det er bare kanon... :o)

vaco : Kan jeg ikke lige få et svar?

Og kan en iøvrigt fortælle mig hvad en pointer helt konkret er?
Avatar billede arne_v Ekspert
13. september 2004 - 07:08 #10
En pointer er en adresse som du har lov til at lege med (i modsætning til
en managed reference som også er en adresse men som du ikke må lege med)
Avatar billede vaco Nybegynder
13. september 2004 - 08:58 #11
fedt du fik det til at virker :-)
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