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. add Space character every 3 letters
Forum Updated to NodeBB v4.3 + New Features

add Space character every 3 letters

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 7 Posters 6.7k Views 3 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #5

    since you are using QByteArray (i.e. 1 character is 1 byte) you can probably optimise it using std::memcpy on the data() pointer.

    QByteArray tarnsform(const QByteArray& seq, int span){
        if(seq.isEmpty() || span<=0) return QByteArray();
        const int oldArrSize = seq.size();
        QByteArray result(oldArrSize  + (oldArrSize /span) - (oldArrSize %span==0),' ');
        auto sourceIter = seq.cbegin();
        auto destIter = result.data();
        const auto srcEnd=seq.cend();
        for(int dstnc = std::distance(sourceIter,srcEnd);dstnc>0;dstnc-=span){
            std::memcpy(destIter,sourceIter,qMin(dstnc,span));
            destIter+=span+1;
            sourceIter+=span;
        }
        return result;
    }
    

    EDIT:

    The code I had before broke memory if seq.size()%span!=0

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    1 Reply Last reply
    1
    • Taz742T Taz742

      @kshegunov
      Your code is small and effective.
      My and your variant is probably the same in time?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #6

      @Taz742 said in add Space character every 3 letters:

      My and your variant is probably the same in time?

      I'd even speculate mine may be faster, even though it uses a regular expression. The problem with your piece of code is that at each insert of a new space you're copying the data after that position - the data has to be shifted, which might be rather heavy. The regular expression code (assuming it can optimize the expression well internally) can do it with a single memory allocation. In fact your code can be modified so it uses one allocation, by just using a resulting byte array and copying the data in chunks of 3 bytes, then setting a space, and then repeating.

      Edit: My view hadn't updated, basically what @VRonin wrote is what I was talking about.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      4
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #7

        Hi
        Fast test. Might have logical issues. Just for fun.

        using namespace std::chrono;
        void MainWindow::on_pushButton_clicked() {
          high_resolution_clock::time_point t1 = high_resolution_clock::now();
        
          for (int var = 0; var < 10000; ++var) {
            int cnt = 0;
            QByteArray seq = "ACGTATAGTACGTACG";
            for(int i = 3; i < seq.size() - 3; i++) {
              if(i % 3 == 0) {
                seq.insert(i + cnt++, ' ');
              }
            }
          }
          high_resolution_clock::time_point t2 = high_resolution_clock::now();
        
          auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
        
          qDebug() << "time: " << duration ;
        }
        
        void MainWindow::on_pushButton_2_clicked() {
        
          high_resolution_clock::time_point t1 = high_resolution_clock::now();
        
          for (int var = 0; var < 10000; ++var) {
            QString split = QString("ACGTATAGTACGTACG").replace(QRegularExpression("(.{3})"), "\\1 ");
          }
          high_resolution_clock::time_point t2 = high_resolution_clock::now();
        
          auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
        
          qDebug() << "time QRegularExpression: " << duration ;
        }
        

        Result:
        time: 9001
        time: 8002
        time: 8001
        time: 8004
        time: 8001
        time: 8001
        time: 7995
        time: 8001
        time: 8001
        time: 8001
        time QRegularExpression: 161033
        time QRegularExpression: 162033
        time QRegularExpression: 161032
        time QRegularExpression: 161032
        time QRegularExpression: 162032
        time QRegularExpression: 162032
        time QRegularExpression: 162033

        VRoninV E 2 Replies Last reply
        2
        • mrjjM mrjj

          Hi
          Fast test. Might have logical issues. Just for fun.

          using namespace std::chrono;
          void MainWindow::on_pushButton_clicked() {
            high_resolution_clock::time_point t1 = high_resolution_clock::now();
          
            for (int var = 0; var < 10000; ++var) {
              int cnt = 0;
              QByteArray seq = "ACGTATAGTACGTACG";
              for(int i = 3; i < seq.size() - 3; i++) {
                if(i % 3 == 0) {
                  seq.insert(i + cnt++, ' ');
                }
              }
            }
            high_resolution_clock::time_point t2 = high_resolution_clock::now();
          
            auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
          
            qDebug() << "time: " << duration ;
          }
          
          void MainWindow::on_pushButton_2_clicked() {
          
            high_resolution_clock::time_point t1 = high_resolution_clock::now();
          
            for (int var = 0; var < 10000; ++var) {
              QString split = QString("ACGTATAGTACGTACG").replace(QRegularExpression("(.{3})"), "\\1 ");
            }
            high_resolution_clock::time_point t2 = high_resolution_clock::now();
          
            auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
          
            qDebug() << "time QRegularExpression: " << duration ;
          }
          

          Result:
          time: 9001
          time: 8002
          time: 8001
          time: 8004
          time: 8001
          time: 8001
          time: 7995
          time: 8001
          time: 8001
          time: 8001
          time QRegularExpression: 161033
          time QRegularExpression: 162033
          time QRegularExpression: 161032
          time QRegularExpression: 161032
          time QRegularExpression: 162032
          time QRegularExpression: 162032
          time QRegularExpression: 162033

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #8

          @mrjj Was that debug or release mode?

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          mrjjM 1 Reply Last reply
          0
          • VRoninV VRonin

            @mrjj Was that debug or release mode?

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by mrjj
            #9

            @VRonin
            both debug. ( but just ran it. not ran as debug)
            You think it affects the result in uneven manner ??
            I till try in release just to be sure.

            1 Reply Last reply
            0
            • mrjjM mrjj

              Hi
              Fast test. Might have logical issues. Just for fun.

              using namespace std::chrono;
              void MainWindow::on_pushButton_clicked() {
                high_resolution_clock::time_point t1 = high_resolution_clock::now();
              
                for (int var = 0; var < 10000; ++var) {
                  int cnt = 0;
                  QByteArray seq = "ACGTATAGTACGTACG";
                  for(int i = 3; i < seq.size() - 3; i++) {
                    if(i % 3 == 0) {
                      seq.insert(i + cnt++, ' ');
                    }
                  }
                }
                high_resolution_clock::time_point t2 = high_resolution_clock::now();
              
                auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
              
                qDebug() << "time: " << duration ;
              }
              
              void MainWindow::on_pushButton_2_clicked() {
              
                high_resolution_clock::time_point t1 = high_resolution_clock::now();
              
                for (int var = 0; var < 10000; ++var) {
                  QString split = QString("ACGTATAGTACGTACG").replace(QRegularExpression("(.{3})"), "\\1 ");
                }
                high_resolution_clock::time_point t2 = high_resolution_clock::now();
              
                auto duration = std::chrono::duration_cast<std::chrono::microseconds>( t2 - t1 ).count();
              
                qDebug() << "time QRegularExpression: " << duration ;
              }
              

              Result:
              time: 9001
              time: 8002
              time: 8001
              time: 8004
              time: 8001
              time: 8001
              time: 7995
              time: 8001
              time: 8001
              time: 8001
              time QRegularExpression: 161033
              time QRegularExpression: 162033
              time QRegularExpression: 161032
              time QRegularExpression: 161032
              time QRegularExpression: 162032
              time QRegularExpression: 162032
              time QRegularExpression: 162033

              E Offline
              E Offline
              Eeli K
              wrote on last edited by
              #10

              @mrjj I think it's fair to optimize a bit:

              QRegularExpression re{"(.{3})"};
              high_resolution_clock::time_point t1 = high_resolution_clock::now();
              ...
              ...QString("ACGTATAGTACGTACG").replace(re, "\\1 ");
              
              mrjjM 1 Reply Last reply
              2
              • E Eeli K

                @mrjj I think it's fair to optimize a bit:

                QRegularExpression re{"(.{3})"};
                high_resolution_clock::time_point t1 = high_resolution_clock::now();
                ...
                ...QString("ACGTATAGTACGTACG").replace(re, "\\1 ");
                
                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #11

                @Eeli-K
                Yes more fair to take out construction of "re"
                I will try that also.

                kshegunovK 1 Reply Last reply
                0
                • mrjjM mrjj

                  @Eeli-K
                  Yes more fair to take out construction of "re"
                  I will try that also.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by
                  #12

                  Designing benchmarking tests isn't exactly trivial, but I'd suggest something too (probably the raw insert will outperform the rx, but still for the sake of argument):

                  Don't use the same fixed size input string; use input that ranges from very short to very long. And do the benchmarking in batches e.g. run the same benchmark for at least 30-40 times and record the time for each run, then you'd get data that can be put into a histogram and you can work it statistically.

                  Read and abide by the Qt Code of Conduct

                  mrjjM 1 Reply Last reply
                  0
                  • kshegunovK kshegunov

                    Designing benchmarking tests isn't exactly trivial, but I'd suggest something too (probably the raw insert will outperform the rx, but still for the sake of argument):

                    Don't use the same fixed size input string; use input that ranges from very short to very long. And do the benchmarking in batches e.g. run the same benchmark for at least 30-40 times and record the time for each run, then you'd get data that can be put into a histogram and you can work it statistically.

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #13

                    @kshegunov
                    Yep varying input lengths might alter the result significantly so will try that too.

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      dridk2
                      wrote on last edited by
                      #14

                      Oh, I was not notify by email of all your answers ! Thanks a lot ! I will try it .
                      By the way, you can join the team for this small project !
                      https://github.com/labsquare/cuteFasta
                      Preview on twitter : https://twitter.com/labsquare/status/884146483406266368

                      1 Reply Last reply
                      1
                      • R Offline
                        R Offline
                        reena jaus
                        wrote on last edited by
                        #15

                        try this : just modify ur for loop
                        i<seq.size()
                        thats it :- enjoy
                        QByteArray seq = "ACGTATAGTACGTACG";

                        int cnt = 0;
                        
                        for(int i = 3; i < seq.size(); i++){
                            if(i % 3 == 0){
                                seq.insert(i + cnt++, ' ');
                            }
                        }
                        
                        qDebug() << seq; = "ACG TAT AGT ACG TAC G"
                        
                        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