Hey Leute,
arbeite momentan an einem 'Spiel' und habe momentan Probleme mit der Performance an den Zielrechnern (Die Zielsystem sind sehr schwach). Bin jetzt schon den ganzen Tag an meinem PC am profilen um Schwachstellen im Programm zu finden. Die meiste Zeit geht an folgenden Teilen verloren:
Zum ersten hab ich nen Timer der nur aktiv ist wenn ein JDialog aufgerufen wird.
Hab dazu mal ein bisschen gegoogelt und dort steht das man das setText() vom Label in nen SwingWorker auslagern soll damit das im EDT-Thread ausgeführt wird. Ist das wirklich sinnvoll jedesmal nen SwingWorker anzulegen um den Text zusetzen? Sollte ich direkt alles, also auch den eigentlichen Timer, in den SwingWorker auslagern? Wie caste ich long performance mäßig am besten? Habt ihr noch andere Vorschläge?
Das zweite Problem liegt in meinem Drag and Drop. Konnte es schon wesentlich verbessern, kann aber erst am Montag gucken ob es reicht für die Zielrechner.
DragComponent extends JLabel und DropComponent extends JComponent. Habe nicht viele Änderungen vorgenommen an den Klassen. Am meisten Zeit geht bei den checkCollision() aufrufen verloren. Weiß aber nicht genau wie ich es anders machen soll.
Das ist das erste Mal das ich auf Performance achten muss. Hab eigentlich keine Ahnung was ich hier mache, geb mir aber Mühe :rtfm: . Hoffe ihr habt ein paar Tipps für mich. Bin natürlich offen für andere Tipps und Tricks sowie no go's auf die ich achten sollte wenn es auf Performance ankommt.
arbeite momentan an einem 'Spiel' und habe momentan Probleme mit der Performance an den Zielrechnern (Die Zielsystem sind sehr schwach). Bin jetzt schon den ganzen Tag an meinem PC am profilen um Schwachstellen im Programm zu finden. Die meiste Zeit geht an folgenden Teilen verloren:
Zum ersten hab ich nen Timer der nur aktiv ist wenn ein JDialog aufgerufen wird.
.sleep() ist nachträglich eingefügt. Performance ist jetzt wesentlich besser geworden, aber bin trotzdem neugierig was ihr dazu sagt.
Java:
private class TimerThreadRunnable implements Runnable {
@Override
public void run() {
long delta = 0, startTime= System.currentTimeMillis();
while (delta < timerTime) {
delta = (System.currentTimeMillis() - startTime) / 1000;
timeLeft.setText(((timerTime - delta)) + " sec. ");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(QuestionFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
frameComponent.setVisible(false);
}
}
Hab dazu mal ein bisschen gegoogelt und dort steht das man das setText() vom Label in nen SwingWorker auslagern soll damit das im EDT-Thread ausgeführt wird. Ist das wirklich sinnvoll jedesmal nen SwingWorker anzulegen um den Text zusetzen? Sollte ich direkt alles, also auch den eigentlichen Timer, in den SwingWorker auslagern? Wie caste ich long performance mäßig am besten? Habt ihr noch andere Vorschläge?
Code:
Thread 45ms
JLabel.setText() 17ms
StringBuilder.append() 16ms
StringBuilder.toString() 7ms
StringBuilder.append() 3.5ms
Das zweite Problem liegt in meinem Drag and Drop. Konnte es schon wesentlich verbessern, kann aber erst am Montag gucken ob es reicht für die Zielrechner.
Java:
private class DnDMotionListener extends MouseInputAdapter implements Runnable {
int innerX, innerY;
int width, heigth;
DragComponent dragComponent, stayingComponent;
boolean enableDrag;
Thread tick;
DnDMotionListener() {
}
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
innerX = e.getX();
innerY = e.getY();
dragComponent = (DragComponent) e.getComponent();
width = dragComponent.getWidth();
heigth = dragComponent.getHeight();
stayingComponent = new DragComponent(dragComponent.getText(), dragComponent.getHorizontalAlignment());
stayingComponent.setBounds(dragComponent.getX(), dragComponent.getY(), width, heigth);
stayingComponent.setFont(dragComponent.getFont());
stayingComponent.setBorder(dragComponent.getBorder());
dragComponent.getParent().add(stayingComponent);
dragComponent.setBorder(null);
dragComponent.setForeground(Color.GRAY);
for (DropComponent c : dropComponents) {
if (dragComponent.getBounds().intersects(c.getBounds())) {
c.setEmpty(true);
}
}
tick = new Thread(this);
tick.start();
enableDrag = true;
}
}
@Override
public void mouseDragged(MouseEvent e) {
if (enableDrag) {
dragComponent.setBounds(dragComponent.getX() + e.getX() - innerX, dragComponent.getY() + e.getY() - innerY, width, heigth);
dragComponent.getParent().repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
enableDrag = false;
boolean validPosition = true;
for (DropComponent c : dropComponents) {
if (dragComponent.getBounds().intersects(c.getBounds()) && c.isEmpty()) {
dragComponent.setBounds(c.getBounds());
c.setEmpty(false);
}
}
for (DragComponent c : dragComponents) {
validPosition &= !checkCollisions(c);
}
if (validPosition) {
dragComponent.setBorder(stayingComponent.getBorder());
dragComponent.setForeground(Color.BLACK);
stayingComponent.setVisible(false);
} else {
dragComponent.setBorder(stayingComponent.getBorder());
dragComponent.setBounds(stayingComponent.getBounds());
dragComponent.setForeground(Color.BLACK);
stayingComponent.setVisible(false);
}
}
}
public boolean checkCollisions(DragComponent dndComponent) {
return !dragComponent.equals(dndComponent) && (dragComponent.getBounds().intersects(dndComponent.getBounds()) || dragComponent.getX() <= 0 || dragComponent.getY() <= 0 || (dragComponent.getX() + width) >= getWidth() || (dragComponent.getY() + heigth) >= getHeight());
}
@Override
public void run() {
boolean validPosition;
while (enableDrag) {
validPosition = true;
for (DragComponent c : dragComponents) {
if (checkCollisions(c)) {
validPosition = false;
}
}
if (!validPosition && enableDrag && dragComponent.getForeground() != Color.RED) {
dragComponent.setForeground(Color.RED);
} else if (validPosition && dragComponent.getForeground() != Color.LIGHT_GRAY) {
dragComponent.setForeground(Color.LIGHT_GRAY);
}
}
}
}
DragComponent extends JLabel und DropComponent extends JComponent. Habe nicht viele Änderungen vorgenommen an den Klassen. Am meisten Zeit geht bei den checkCollision() aufrufen verloren. Weiß aber nicht genau wie ich es anders machen soll.
Das ist das erste Mal das ich auf Performance achten muss. Hab eigentlich keine Ahnung was ich hier mache, geb mir aber Mühe :rtfm: . Hoffe ihr habt ein paar Tipps für mich. Bin natürlich offen für andere Tipps und Tricks sowie no go's auf die ich achten sollte wenn es auf Performance ankommt.