Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QT code slower than java file for processing.
Forum Updated to NodeBB v4.3 + New Features

QT code slower than java file for processing.

Scheduled Pinned Locked Moved General and Desktop
15 Posts 4 Posters 3.9k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    nurtan
    wrote on last edited by
    #5

    ok , I'll try to use QByteArray , but because the code set in the open window in the application is slower than in the sample application . where performance is dramatically changed

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mcosta
      wrote on last edited by
      #6

      As I said, the best way to find bottlenecks is to use some profiling tool

      Once your problem is solved don't forget to:

      • Mark the thread as SOLVED using the Topic Tool menu
      • Vote up the answer(s) that helped you to solve the issue

      You can embed images using (http://imgur.com/) or (http://postimage.org/)

      1 Reply Last reply
      0
      • N Offline
        N Offline
        nurtan
        wrote on last edited by
        #7

        I have changed from QString to QByteArray and has improved a lot, in the application of test, time has gone down to 350 milliseconds, making it as fast as java. But when I bring changes to the real application, time went down from f 2300 milliseconds to 1300 milliseconds but still far from 350 milliseconds that it takes for the test application.
        I'm looking for a profiler to see what is going on.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mcosta
          wrote on last edited by
          #8

          Sorry I can't help you but I think you can find something using Gooogle

          Once your problem is solved don't forget to:

          • Mark the thread as SOLVED using the Topic Tool menu
          • Vote up the answer(s) that helped you to solve the issue

          You can embed images using (http://imgur.com/) or (http://postimage.org/)

          1 Reply Last reply
          0
          • H Offline
            H Offline
            Huulivoide
            wrote on last edited by
            #9

            Why are you storing the values as strings in the class?
            You should use references when taking stuff in, to avoid an extra allocation
            on each function call, also you code is not const correct, fixing that might
            help the compiler optimize your code better.

            1 Reply Last reply
            0
            • N Offline
              N Offline
              nurtan
              wrote on last edited by
              #10

              With references do you mean to use QStringRef, why my code is not const correct, could you give me an example?

              Thank you.

              H 1 Reply Last reply
              0
              • N nurtan

                With references do you mean to use QStringRef, why my code is not const correct, could you give me an example?

                Thank you.

                H Offline
                H Offline
                Huulivoide
                wrote on last edited by Huulivoide
                #11

                @nurtan

                No with references I mean reference void myFunc(QString& str)
                with const-correctness I mean that none of your functions or the parameters
                they take in are marked const, even tough they are const.

                I take it you are not very familiar with C++, you should learn C++ properly
                before using Qt. C++ can be used to make efficient programs if one knows
                his way around C++, but if he doesn't things will go wrong.

                Your code clearly shows you have now idea about the differences of pointer
                and value types, as you are doing to "null-pointer" check on variables that
                can never contain null-pointers.

                http://www.cprogramming.com/tutorial/references.html
                https://isocpp.org/wiki/faq/const-correctness

                /* Example of a good function
                / str is passed as a reference, no copy is made */
                QString myFunc(const QString& str, QPushButton* mutableButton) const
                {
                    QIcon icon(QString("/the/str/is/not/changed/so/it/is/const/") + str);
                    mutableButton->setIcon(icon);
                    // A non-const member function is called on mutableButton,
                    // that is it is being changed somehow. So it is not const
                }
                

                Also the following piece of code makes no sense.

                QString Coordenada2::getY()
                {
                    /* This reads as: If empty return a new version of empty
                       Also you should use y.isEmpty() to check if the string is empty */
                    if (y == QString::null)
                        return "";
                
                    // You can just do this. If it is empty the returned value will be same
                    // as 'return "";'
                    return y;
                }
                
                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mcosta
                  wrote on last edited by
                  #12

                  to add something to @Huulivoide ; at the moment passing a QString by value is not so expensive because Qt uses Implicit Sharing (there's only a reference counter incremented)

                  Once your problem is solved don't forget to:

                  • Mark the thread as SOLVED using the Topic Tool menu
                  • Vote up the answer(s) that helped you to solve the issue

                  You can embed images using (http://imgur.com/) or (http://postimage.org/)

                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by Chris Kawa
                    #13

                    @mcosta Still, even with implicit sharing, creating a new instance, copying a data pointer and incrementing a refcount in a thread safe manner is a lot more expensive than simply passing a const reference (which is basically 0 footprint operation when an optimizer passes through). That's why passing "in" parameters as const references is always the preferred way.

                    @nurtan There are many little problems with code above. The const ref parameters are one of them but there are others.
                    For example constructing empty string via "". Empty strings should always be constructed with QString() constructor. You migt say it's the same but constructing string with "" calls QString(const char*) which requires at least some code to determine the buffer is empty (it's not as there is null terminator really).

                    Checking if string is empty by calling operator== and QString::null is also a bad idea. Whenever possible use methods like isNull or isEmpty. They might do the same but also might be more efficient, e.g. by just checking internal character count (integer comparison instead of string comparison).

                    Another big problem is storing everything as strings, even things that are evidently numbers, like x, or mantissa. String comparison is never gonna be anywhere close to what you can get with plain integers.

                    Yet another problem is when reading the file. Creating a new string each line is wasteful. Create the string once, call reserve on it with the anticipated number of characters and then reuse it. That one is small when compared to IO overhead, but it's good to get in habit of not neglecting small gains.

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      nurtan
                      wrote on last edited by
                      #14

                      Today I tried to see why the execution time was different in the test application versus real application, I found an error in the code of the test application. Once the error was corrected, the time in the application of test and the real one are equal, but comparing times with java, thus are very different. Java uses 350 milliseconds but in QT, the time is 1964 milliseconds using Qstring and 1190 milliseconds using QByteArray.

                      I know the c ++ but in the last 15 years I have been programming in Java, where some things are different.

                      About your question , @Huulivoide , of why I store values as strings, it is because I need to have those values to operate them later, store, string or float does not matter because I operate both strings as float

                      I tried to pass and return by reference as you indicate and times have fallen to 1632 in the case of using QString and 1133 in the case of QByteArray, well above on java's time.

                      the getY () function that you indicate me, it is so as It is copied from java, java a null string is different than the empty string and you can not ask if a null string is empty with .isEmpty (), in QT I've noticed that .isEmpty () you can use it with a null string.

                      @Chris-Kawa, I will try what you have indicated me, the class stores the String because in subsequent processes I work with such data as strings, also as floats but I have more operations with strings than floats.

                      1 Reply Last reply
                      0
                      • N Offline
                        N Offline
                        nurtan
                        wrote on last edited by nurtan
                        #15

                        I've made the changes that you have told me, both using QString as QByteArray classes, times have improved compared to the first post, and using QByteArray has been faster than QString , so I have taken this option.

                        Coordenada.cpp

                        QByteArray &Coordenada2::getComentario() {
                            return comentario;
                        }
                        
                        
                        void Coordenada2::setComentario(const QByteArray &comentario) {
                            this->comentario = comentario;
                        }
                        
                        
                        Coordenada2::Coordenada2() {
                            x=QByteArray("0");
                            y=QByteArray("0");
                            z=QByteArray("0");
                            mantisa=QByteArray("");
                        }
                        
                        QByteArray &Coordenada2::getMantisa(){
                            return mantisa;
                        }
                        QByteArray Coordenada2::getMantisa(const QByteArray &dato) {
                                QByteArray mantisa= QByteArray("");
                                for (int x = 0; x < dato.length(); x++) {
                                    switch (dato.at(x)) {
                                        case 'G':
                                        case 'X':
                                        case 'Y':
                                        case 'Z':
                                        case 'M':
                                        case 'H':
                                        case 'R':
                                        case 'A':
                                        case 'I':
                                        case 'J':
                                        case 'K':
                                        case 'S':
                                        case 'T':
                                        case 'P':
                                        case 'F':
                                            mantisa.append(dato.at(x));
                                            mantisa.append("");
                                    }
                                }
                                return mantisa;
                        }
                        void Coordenada2::setMantisa(const QByteArray &datos) {
                            mantisa = getMantisa(datos);
                        }
                        
                        Coordenada2::Coordenada2(const QByteArray &lineacodigo) {
                            procesaLinea(lineacodigo);
                            setMantisa(lineacodigo);
                        }
                        
                        bool Coordenada2::isX() {
                            return !x.isEmpty();
                        }
                        
                        bool Coordenada2::isY() {
                            return !y.isEmpty();
                        }
                        
                        bool Coordenada2::isZ() {
                            return !z.isEmpty();
                        }
                        
                        QByteArray &Coordenada2::getX() {
                            return x;
                        }
                        
                        float Coordenada2::getNumeroX() {
                            if (x.isEmpty()) {
                                return 0;
                            }
                            return x.toFloat();
                        }
                        
                        void Coordenada2::setX(const QByteArray &x) {
                            this->x = x;
                            anadeMantisa("X");
                        }
                        
                        void Coordenada2::setX(const float &x) {
                            this->x = QByteArray(reinterpret_cast<const char *>(&x), sizeof (x));
                            anadeMantisa("X");
                        }
                        
                        QByteArray &Coordenada2::getY() {
                            return y;
                        }
                        
                        float Coordenada2::getNumeroY() {
                            if (y.isEmpty()) {
                                return 0;
                            }
                            return y.toFloat();
                        }
                        
                        void Coordenada2::setY(const QByteArray &y) {
                            this->y = y;
                            anadeMantisa("Y");
                        }
                        
                        void Coordenada2::setY(const float &y) {
                            this->y=QByteArray(reinterpret_cast<const char *>(&y), sizeof (y));
                            anadeMantisa("Y");
                        }
                        
                        QByteArray &Coordenada2::getZ() {
                            return z;
                        }
                        
                        float Coordenada2::getNumeroZ() {
                            if (z.isEmpty()) {
                                return 0;
                            }
                            return z.toFloat();
                        }
                        
                        void Coordenada2::setZ(const QByteArray &z) {
                            this->z = z;
                            anadeMantisa("Z");
                        }
                        
                        void Coordenada2::setZ(const float &z) {
                            this->z = QByteArray(reinterpret_cast<const char *>(&z), sizeof (z));
                            anadeMantisa("Z");
                        }
                        
                        void Coordenada2::anadeMantisa(const QByteArray parametro) {
                            if (mantisa.isEmpty()) {
                                mantisa = parametro;
                            }
                            if (!mantisa.contains(parametro)) {
                                mantisa.append(" ");
                                mantisa.append(parametro);
                            }
                        }
                        void Coordenada2::procesaLinea(const QByteArray &codigo) {
                            int pos = 0;
                            comentario = QByteArray("");
                            while (pos < codigo.length()) {
                                char letra = codigo.at(pos++);
                                if (pos >= codigo.length()) {
                                    if (letra == '/') {
                                        comentario = QByteArray("/");
                                    } else {
                                        comentario.append(letra);
                                    }
                                    break;
                                }
                                switch (letra) {
                                    case 'X':
                                        if (!isNumeric(codigo.at(pos)) && codigo.at(pos) != '-' && codigo.at(pos) != '+') {
                                            comentario.append(letra);
                                            break;
                                        }
                                        x=QByteArray("");
                                        while (pos < codigo.length() && (isNumeric(codigo.at(pos)) || codigo.at(pos) == '.' || codigo.at(pos) == '-' || codigo.at(pos) == '+')) {
                                            letra = codigo.at(pos++);
                                            x.append(letra);
                                        }
                                        break;
                                    case 'Y':
                                        if (!isNumeric(codigo.at(pos)) && codigo.at(pos) != '-' && codigo.at(pos) != '+') {
                                            comentario.append(letra);
                                            break;
                                        }
                                        y=QByteArray("");
                                        while (pos < codigo.length() && (isNumeric(codigo.at(pos)) || codigo.at(pos) == '.' || codigo.at(pos) == '-' || codigo.at(pos) == '+')) {
                                            letra = codigo.at(pos++);
                                            y.append(letra);
                                        }
                                          break;
                                    case 'Z':
                                        if (!isNumeric(codigo.at(pos)) && codigo.at(pos) != '-' && codigo.at(pos) != '+') {
                                            comentario.append(letra);
                                            break;
                                        }
                                        z=QByteArray("");
                                        while (pos < codigo.length() && (isNumeric(codigo.at(pos)) || codigo.at(pos) == '.' || codigo.at(pos) == '-' || codigo.at(pos) == '+')) {
                                            letra = codigo.at(pos++);
                                            z.append(letra);
                                        }
                                        break;
                                    default:
                                        if (letra != ' ') {
                                            do {
                                                comentario.append(letra);
                                                if (pos < codigo.length()) {
                                                    letra = codigo.at(pos++);
                                                }
                                            } while (pos < codigo.length() && letra != ' ');
                                            if (pos <= codigo.length()) {
                                                comentario.append(letra);
                                            }
                                        }
                                        break;
                                }
                            }
                            if (this->comentario.length() > 0 && !(this->comentario.at(0))=='/') {
                                if (x.length()>0 || y.length()>0 || z.length() ) {
                                    if (comentario.length()>0) {
                                        this->comentario.clear();
                                    }
                                }
                            }
                        }
                        
                        bool Coordenada2::isComentario() {
                            return !comentario.isEmpty();
                        }
                        
                        bool Coordenada2::isNull() {
                            if (!this->isX() && !this->isY() && !this->isZ()) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                        
                        bool Coordenada2::isNumeric(const char &cadena) {
                            if ('0' <= cadena && cadena <= '9' )
                                return true;
                            else
                                return false;
                        }
                        

                        main.cpp

                        void leeArchivo(){
                        QFile archivo("c:\\coordenadas.txt");
                        int lineas = 0;
                        float maxX = -10000;
                        float maxY = -10000;
                        float minX = 10000;
                        float minY = 10000;
                        float maxZ = -10000;
                        float minZ = 10000;
                        bool hayX = false;
                        bool hayY = false;
                        Coordenada2 elementoAnterior();
                        if (archivo.open(QIODevice::ReadOnly | QIODevice::Text)){
                            QTextStream in(&archivo);
                            QElapsedTimer tiempo;
                            tiempo.start();
                            while (!in.atEnd()) {
                                lineas++;
                                Coordenada2 elemento(in.readLine().toLatin1());
                                if (maxX < elemento.getNumeroX()) {
                                    maxX = elemento.getNumeroX();
                                }
                                if (minX > elemento.getNumeroX()) {
                                    minX = elemento.getNumeroX();
                                }
                                if (maxY < elemento.getNumeroY()) {
                                    maxY = elemento.getNumeroY();
                                }
                                if (minY > elemento.getNumeroY()) {
                                    minY = elemento.getNumeroY();
                                }
                                if (maxZ < elemento.getNumeroZ()) {
                                    maxZ = elemento.getNumeroZ();
                                }
                                if (minZ > elemento.getNumeroZ() ) {
                                    minZ = elemento.getNumeroZ();
                                }
                                if (elemento.isX()) {
                                    hayX = true;
                                }
                                if (elemento.isY()) {
                                    hayY = true;
                                }
                            }
                            qDebug()<<"Tiempo :"<<tiempo.elapsed();
                            qDebug()<<maxX;
                            archivo.close();
                        }
                        }
                        
                        int main(int argc, char *argv[])
                        {
                        QApplication a(argc, argv);
                        
                        leeArchivo();
                        return 0;
                        }
                        

                        I've been testing to measure the creation times of Coordenada2 object for the first 50 lines of the file, and the result has been that Java was slower than QT creating each of the objects. But for the total of java linesis still much faster. I made a test by increasing the number of records and comparing the result in java and QT. The results are as follows:

                         java     QT  	lines
                            1	   0	    10
                            3	   0	   100
                            8	   1   	   300
                           13      2	  1000
                           18	   8	  3000
                           25	  27     10000
                           46	  84	 30000
                          104    295	100000
                          289	 936	300000
                          349	1199	371723
                        

                        As you can see java is much more lineal in time, every time we increase records, the time increases , however QT has some very good times to 10000 lines, but from there, the times are far higher than those of java. Any idea why his happens'

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved