Hi,

Well how about this then, I've reimplemented both the Java and the C++ version to be identical. They both use arrays and only brushes are cached since it's not a good idea to new stuff during painting. Now I get 20.7 fps in Java and 15.3 fps in c++ on my Ubuntu box running on a Dell M90 laptop, thats about 35% faster in Java....

-=Børge

Gunnar Sletta wrote:
Børge Austvold wrote:

Hi,

I had some available time now before x-mas and did some tests on OpenGL performance. I had a feeling for some reasons that writing OpenGL applications in Java had be to slower that native ones in C++. So, to test this I fired up an simple application that paints 10000 rectangles and 50 images with some opacity using a QPainter on a QGLWidget. I wrote the same application in C++ using QT 4.4 and in Java using Jambi 4.4. On the first run the java application stopped every 5th second to garbage collect. When I removed all allocations and cached some random calculations (in both c++ and java) the java application is running 30% faster on my Dell M90 laptop running both Linux Mint (Ubuntu 8.10) and Windows Vista. The linux version in java (and c++) is also running significant faster than on Vista.

Did some more testing and It seems like the java version is always faster than the c++ version. The only exception was when I tested this on a KDE 4.1 machine. There the C++ version ran faster.... How can this be possible? Is the HotSpot stuff from sun able to optimize passed the JNI in the stack ?

Any thoughts on this ?

There are two reasons for the difference that I can see. The startup time to get the pixmap loaded into graphics memory etc seems to be a bit costly, so I reset the timer every 5 sec. Then I noticed that you preincrement the counter in java and postincrement it in C++, meaning that you will count one less frame in C++, and since the code is running at 19 Fps (at least on my machine, this will affect the output).

The initialization of the data is also quite different and the speed is dependent on how much of the pixels are being written and read and speed is far more dependent on how much you're actually drawing than on the runtime. If you sync up the implementations, the two will perform pretty much identical.

best regards,
Gunnar



import com.trolltech.qt.QtBlockedSlot;
import com.trolltech.qt.core.QPoint;
import com.trolltech.qt.core.QSize;
import com.trolltech.qt.core.QTimer;
import com.trolltech.qt.gui.*;
import com.trolltech.qt.opengl.QGLWidget;

import java.util.Random;

/**
 * @author Børge Austvold
 */
public class TestOpenGL extends QGLWidget {

    private QTimer timer = new QTimer();
    private QPixmap image = new QPixmap("../image.png");

    private QPoint[] poses = new QPoint[50];
    private Random random = new Random();
    private long startTime = System.currentTimeMillis();
    private int counter;

    private QBrush[] brush = new QBrush[100];
    private int brushPointer;

    public TestOpenGL() {

        timer.setInterval(0);
        timer.setSingleShot(false);
        timer.timeout.connect(this, "animate()");

        for (int a = 0; a < poses.length; a++) {
            poses[a] = new QPoint(0, 0);
        }

        for (int i = 0; i < brush.length; i++) {
            brush[i] = new QBrush(new QColor(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
        }
        timer.start();

    }

    public void animate() {

        int w = width();
        int h = height();

        for (QPoint point : poses) {

            int nx = point.x() + random.nextInt(10);
            int ny = point.y() + random.nextInt(10);

            point.setX(nx > w ? 0 : nx);
            point.setY(ny > h ? 0 : ny);

        }

        update();

    }

    @QtBlockedSlot
    protected void paintEvent(QPaintEvent arg__1) {

        QPainter painter = new QPainter(this);

        painter.setOpacity(0.3);
        for (int a = 0; a < 10000; a++) {
            if (++brushPointer == brush.length) {
                brushPointer = 0;
            }
            painter.fillRect(random.nextInt(width()), random.nextInt(height()), 50, 50, brush[brushPointer]);
        }

        painter.setOpacity(0.5);

        for (QPoint point : poses) {
            painter.drawPixmap(point, image);
        }
        painter.drawText(100, 100, String.valueOf(++counter / ((System.currentTimeMillis() - startTime) / 1000.0)));
    }

    public static void main(String[] args) {
        QApplication.initialize(args);
        new TestOpenGL().showFullScreen();
        QApplication.exec();
    }

}

#include "widget.h"
#include <QPainter>


Widget::Widget()
    : QGLWidget(), _counter( 0 )
{

    _pixmap.load( "../image.png" );

    connect( &_timer, SIGNAL( timeout() ), SLOT( animate() ) );
    _timer.start(0);

    for (int a = 0; a < 50; a++) {
        _points[a].setX(0);
        _points[a].setY(0);
    }


    for ( int i = 0; i < 100; ++i ) {
        _brushes[i] = QBrush( QColor( rand() % 255, rand() % 255, rand() % 255 ) );
    }

    _time.start();

}

Widget::~Widget()
{

}

void Widget::animate() {

    int w = width();
    int h = height();
    for(int a = 0; a < 50; a++){
        int nx = _points[a].x() + rand() % 10;
        int ny = _points[a].y() + rand() % 10;
        _points[a].setX(nx > w ? 0 : nx);
        _points[a].setY(ny > h ? 0 : ny);
    }

    update();
}

void Widget::paintEvent( QPaintEvent* e ) {

    QPainter p( this );

    int brushPointer = 0;
    p.setOpacity( 0.3 );
    for (int a = 0; a < 10000; a++) {
        if (++brushPointer == 100 ) brushPointer = 0;
        p.fillRect(rand() % width(), rand() % height(), 50, 50, _brushes[brushPointer]);
    }

    p.setOpacity( 0.5 );

    for( int a = 0; a<50; a++){
        p.drawPixmap(_points[a], _pixmap );
    }

    double fps = _counter++ / ( _time.elapsed() / 1000.0 );
    p.drawText( 100, 100, QString::number( fps ) );

}
#ifndef WIDGET_H
#define WIDGET_H

#include <QGLWidget>
#include <QList>
#include <QPixmap>
#include <QTimer>
#include <QTime>

class Widget : public QGLWidget
{
    Q_OBJECT

public:
    Widget();
    ~Widget();

protected:
    void paintEvent( QPaintEvent* e );

private:
    QPoint _points[50];
    QBrush _brushes[100];
    QPixmap _pixmap;
    QTimer _timer;
    int _counter;
    QTime _time;

private slots:
    void animate();

};

#endif // WIDGET_H
_______________________________________________
Qt-jambi-interest mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt-jambi-interest

Reply via email to