Zusammehang der Geschwindikeit mit Windows-Version?



  • Grüß Gott.
    Ich habe ein Programm geschrieben, dass die Pixelfarbe von Pixeln in einem bestimmten Bereich ermittelt und diese dann in einem Fenster zeichnet. Sozusagen ein kleiner Screenshot.

    Nur ich habenun eine sehr seltsame Erfahrung gemacht:
    Bei Windows XP(Pentium 4 3,0 Ghz, 1 GB Ram) dauert der Vorgng ca 30 Sekunden
    Bei Windows Vista 32Bit, 2 GB RAM, 1,8GHz Core2Duo - 239304 milliseconds ~4min
    Bei Windows 7 64-Bit, 4 GB RAM, 2,7 GHz Core i5 - 323250ms rund 5 Minuten

    Da kann doch rgendetwas nicht stimmen?
    Hier mal der Code.
    Wäre auch gut wen ihr eure Ergebnisse + System posten könntet

    import java.awt.*;
    /**
     * Beschreiben Sie hier die Klasse Test.
     *
     * @author (Ihr Name)
     * @version (eine Versionsnummer oder ein Datum)
     */
    class CrappyDrawTest extends Frame
    {
     public static void main(String[] args)
        {
            CrappyDrawTest t = new CrappyDrawTest();
        }
    
        CrappyDrawTest()
                {
    
                super("Kleiner Screen");
                setLayout(new FlowLayout());
                setSize(200,400);
                setLocation(200,100);
                getMinimumSize();
                this.setVisible(true);
               }
    
       public void paint(Graphics g)
       {
           long t0 = System.currentTimeMillis();
           try
            {
                //Ermitteln der Pixelfarbe
                Robot rob = new Robot();                
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
            int x = 1, y = 15;
            while(y <= 400)
            {
                long te = System.currentTimeMillis();
                try
                {
                    //Ermitteln der Pixelfarbe
                    Robot rob = new Robot();
                    Color clr = rob.getPixelColor(x, y);
    
                    g.setColor(clr);
                }
                catch(Exception e)
                {
                    System.out.println(e);
                }
                //Zeichnen
                g.fillRect(x,y, 1, 1);
                x++;
                if(x > 30)
                {
                    y++;
                    x=1;
                }
                long dif = System.currentTimeMillis() - te;
                System.out.println("Dieser Pixel dauerte " + dif + "ms");
            }
            System.out.println( "paint finished in " + (System.currentTimeMillis()-t0) + "ms");
        }
    }
    

    Programm wurde inBlueJ, Eclipse und als JAR gestartet.

    bitte um eu Hilfe

    mfg Face



  • Ich habe zwar keine Zahlen dafür in paar Kommentarezum Quelltext

    Der Code ist deswegen so lahm da du du beim Setzen jedes Pixels einzelnd die Dauer ausgibst und das ist wahrschinlich das was am meisten Zeit benötigt.

    FaceToFace schrieb:

    class CrappyDrawTest
    

    Stimmt sehr Crappy 🙄

    FaceToFace schrieb:

    public void paint(Graphics g)
       {
           /*   ...   */
           try
            {
                //Ermitteln der Pixelfarbe
                Robot rob = new Robot();                
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
    /*  ...   */
    

    Wozu der Code am Anfang ???? Der hat doch gar keine Funktion

    FaceToFace schrieb:

    int x = 1, y = 15;
            while(y <= 400)
    

    For-Schleife???

    FaceToFace schrieb:

    long te = System.currentTimeMillis();
                try
                {
                    //Ermitteln der Pixelfarbe
                    Robot rob = new Robot();
                    Color clr = rob.getPixelColor(x, y);
                    
                    g.setColor(clr);
                }
                catch(Exception e)
                {
                    System.out.println(e);
                }
                //Zeichnen
                g.fillRect(x,y, 1, 1);
                x++;
                if(x > 30)
                {
                    y++;
                    x=1;
                }
    }
    

    Warum erstellst du den Robot innerhalb der WhileSchife immer neu?



  • Habe den Code noch etwas verändert gehabt,aber den falschen reinkopiert:

    import java.awt.*;
    /**
     * Beschreiben Sie hier die Klasse Test.
     *
     * @author (Ihr Name)
     * @version (eine Versionsnummer oder ein Datum)
     */
    class CrappyDrawTest extends Frame
    {
     public static void main(String[] args)
        {
            CrappyDrawTest t = new CrappyDrawTest();
        }
    
        CrappyDrawTest()
                {
    
                super("Kleiner Screen");
                setLayout(new FlowLayout());
                setSize(200,400);
                setLocation(200,100);
                getMinimumSize();
                this.setVisible(true);
               }
    
       public void paint(Graphics g)
       {
           long t0 = System.currentTimeMillis();
           Robot rob = null;
           try
            {
                //Ermitteln der Pixelfarbe
                rob = new Robot();                
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
            int x = 1, y = 15;
            while(y <= 400)
            {
                long te = System.currentTimeMillis();
                Color clr = rob.getPixelColor(x, y);
                g.setColor(clr);
                //Zeichnen
                g.fillRect(x,y, 1, 1);
                x++;
                if(x > 30)
                {
                    y++;
                    x=1;
                }
                long dif = System.currentTimeMillis() - te;
                System.out.println("Dieser Pixel dauerte " + dif + "ms");
            }
            System.out.println( "paint finished in " + (System.currentTimeMillis()-t0) + "ms");
        }
    }
    

    Aber wieso sllte ich ein for-Schleife machen? Ich weiß sie ist viel kompakter, aber st sie auch schneller? Ich wollte das ganze auch nicht umschreiben, kann ic aber auch machen.

    mfg Face

    P.S.: Der Cod am Anfang, war weil es am Anfang nicht funktioniet hat und ich wissen wollte ob es eine Exception gibt^^



  • 1.) Lieber JFrame benutzen statt Frame. JFrame ist Swing (leichtgewichtig), während Frame AWT ist (schwergewichtig).
    2.) IdR niemals paint() überschreiben! Stattdessen paintComponent() überschreiben und dort die Zeichenlogik rein!
    3.) Du solltest keine rechenintensiven Operationen in paintComponent() machen! Stattdessen Farben vorher auslesen und in paintComponent() nur noch zeichnen.
    4.) Niemals nie System.out für zeitkritische Logik benutzen, schon gar nicht wenn Du die Ausführungszeit misst! Benutze stattdessen einen Logger wie log4j. Das ist deutlich performanter (kostet aber immernoch Zeit).



  • Dein Code braucht bei mir ca. 500ms. Aber warum so umständlich?

    import java.awt.*;
    import java.awt.image.BufferedImage;
    
    class BetterDrawTest extends Frame {
    
    	public static void main(String[] args) throws AWTException {
    		new BetterDrawTest();
    	}
    
    	private final Robot rob;
    
    	private BetterDrawTest() throws AWTException {
    		super("Kleiner Screen");
    
    		rob = new Robot();
    
    		setBounds(200, 100, 200, 400);
    		this.setVisible(true);
    	}
    
    	public void paint(Graphics g) {
    		long t0 = System.currentTimeMillis();
    		BufferedImage img = rob.createScreenCapture(
    				new Rectangle(0, 0, 30,	400));
    		g.drawImage(img, 30, 30, null);
    		System.out.println("paint finished in "
    				+ (System.currentTimeMillis() - t0) + "ms");
    	}
    }
    

    Das braucht im schlechtesten Fall 15ms bei mir.



  • Weil ich etwas anderes noch nicht gelernt habe... und so habe ich probiert mir eine eigene "Screenshot-Methode" zu machen. Und dabei ist mir halt aufgefallen, dass es deutlich langsamer als auf XP geht.
    Den Grund habe ich auch schon: Windows Aero. WEnn es deaktiviert ist benötigt der Code ca 500 ms.

    Ist aber auch Blöd um das Programm zu starten extra Aero auszumachen.

    Vielen Dank für eure Hilfe und ich werde eure Ratschläge natürlich versuchen in meinem Programm zu berücksichtigen.

    Viele Grüße

    P.S.: Gibt es eine Möglichkeit, dass wenn das Programm aufgerufen wird der Windows Style auf Klassisch gesetzt wird? Da ist Aero nämlich deaktiviert.



  • Evtl neue JDK/JRE installieren, dein Code braucht bei mir 2000 ms auf Windows 7 mit Aero. Bei deutlich ältere Hardwareausstatung, AMD X2.


Anmelden zum Antworten