Vorneweg: Das könnte schwierig werden.
Es ist nicht klar, wo du die Zeit misst. Der Beschreibung nach könnte es auch
long before = System.nanoTime();
for (int i=0; i<1000; i++) component.repaint();
long after = System.nanoTime();
sein, aber das würde natürlich keinen Sinn machen: repaint() sagt nur: „Zeiche bei Gelegenheit mal neu“, aber das eigentliche Zeichnen ist entkoppelt davon. Außerdem werden mehrere schnell hintereinaderfolgende Aufrufe von ‚repaint()‘ zusammengefasst, so dass z.B. bei 100 Aufrufen von ‚repaint()‘ nur 10 mal wirklich neu gezeichnet wird.
Das einzig potentiell sinnvolle könnte sowas sein wie
@Override
protected void paintComponent(Graphics g)
{
long before = System.nanoTime();
super.paintComponent(g);
long after = System.nanoTime();
...
}
in der „obersten“ Klasse der Zeichenhierarchie. (Wenn man das in einem JFrame machen wollte, müßte man das in paint() reinbasteln, aber … in einem JFrame wird eigentlich nichts gezeichnet, was messbar viel Zeit erfordern würde. Deswegen würde man diese Zeitmessung wohl in einer von JPanel abgeleiteten Klasse einfügen, das die einzige JComponent ist, die in der ContentPane eines Frames liegt, und die ALLE Components enthält, die irgendwelche eigenen painting-Operationen (wie etwa g.drawLine(…)) durchführen).
Um das ganze dann für mehrere Durchläufe zu testen, könnte man ganz pragmatisch sowas machen wie
class BenchmarkingPanel extends JPanel
{
private long sumNS = 0;
private int inverval = 10000;
private int frameCounter = 0;
@Override
protected void paintComponent(Graphics g)
{
long before = System.nanoTime();
super.paintComponent(g);
Toolkit.getDefaultToolkit().sync(); // Siehe "Erklärung" unten im Text
long after = System.nanoTime();
sumNS += (after-before);
frameCounter++;
if (frameCounter == interval)
{
double avgMS = sumNS / interval / 1e6;
System.out.println("Average ms: "+avgMS);
sumNS = 0;
frameCounter = 0;
}
}
}
Und dann dafür sorgen, dass 10000 mal neu gezeichnet wird (wie auch immer man das macht, weil bei 10000 repaint()-Aufrufen ja vielleicht nur 10mal oder 100mal neu gezeichnet wird ;))
Zu dem
Toolkit.getDefaultToolkit().sync();
Ich habe es noch nie benutzt, und wohl auch nie gebraucht, und bin nicht ganz sicher, was es macht, aber glaube, dass man es hier zumindest der Vollständigkeit halber einfügen sollte Das auch zu der allgemeinen Aussage: Das könnte schwierig werden. Java/Swing abstrahiert schon sehr stark vom eigentlichen Zeichensystem. Das ist gut so, weil nur damit so herrlich einfache, praktische Klassen wie Graphics2D möglich sind, und nur so Plattformunabhängigkeit erreicht werden kann. Aber es hat auch zur Folge, dass die Frage, wann wie viele Pixel in den Grafikkartenspeicher geschrieben werden, schwierig zu beantworten sein kann.
Je nachdem, was das eigentliche Ziel ist, könnte ein Profilerlauf vielleicht sinnvoll sein. Oder sich mal mit Dingen wie „active Rendering“ befassen, weil man damit vielleicht, stark vereinfacht gesagt, mehr Kontrolle darüber hat, WANN genau WAS „zum Bildschirm geschickt“ wird.