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. Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB

Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB

Scheduled Pinned Locked Moved General and Desktop
64 Posts 7 Posters 10.5k Views
  • 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.
  • D DerReisende

    @TheLumbee Using floats instead of doubles should minimize memory usage. And my solution was made with Qt 6.4

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #23

    @DerReisende
    Purely OoI: with your 6.4 did you just try the original QDateTime::fromString() as-was, did that have a significant improvement over the "buggy" previous one?

    D 1 Reply Last reply
    0
    • JonBJ JonB

      @DerReisende
      Purely OoI: with your 6.4 did you just try the original QDateTime::fromString() as-was, did that have a significant improvement over the "buggy" previous one?

      D Offline
      D Offline
      DerReisende
      wrote on last edited by
      #24

      @JonB QDateTime::fromString without any optimization takes 37 seconds to complete --> slow as hell.
      I tested performance of QDate::fromString in all Qt6 versions on windows and it NEVER got any faster - thats why I am using the posted cache approach to increase the performance in my app.

      1 Reply Last reply
      1
      • JoeCFDJ Offline
        JoeCFDJ Offline
        JoeCFD
        wrote on last edited by JoeCFD
        #25

        Rust is made for quicker performance. Qt is made for HMI and speed is not the key feature.
        If there are bottlenecks in your app, you can add Rust lib to handle them. If you know Rust well, the big banks will like to have you for high-speed trading apps. Rust is getting popular now and it is something: good to know.

        T 1 Reply Last reply
        0
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #26

          The problem with QDateTime is that for every call the internal format parser (QDateTimeParser, private class) is re-created and needs to re-evaluate the string. This takes a lot of time.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          JonBJ 1 Reply Last reply
          3
          • Christian EhrlicherC Christian Ehrlicher

            The problem with QDateTime is that for every call the internal format parser (QDateTimeParser, private class) is re-created and needs to re-evaluate the string. This takes a lot of time.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #27

            @Christian-Ehrlicher
            This is true, but you have to reflect on Rust is using its NaiveDateTime::parse_from_str(dt, "%Y%m%d %H%M%S %f") for this and is 30x-odd faster. That is not an "acceptable" difference, and the question is what to do from Qt to get acceptable performance regardless of the reasons?

            Christian EhrlicherC 1 Reply Last reply
            0
            • JonBJ JonB

              @Christian-Ehrlicher
              This is true, but you have to reflect on Rust is using its NaiveDateTime::parse_from_str(dt, "%Y%m%d %H%M%S %f") for this and is 30x-odd faster. That is not an "acceptable" difference, and the question is what to do from Qt to get acceptable performance regardless of the reasons?

              Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by Christian Ehrlicher
              #28

              @JonB said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

              nd the question is what to do from Qt to get acceptable performance regardless of the reasons?

              compare rust with std::get_time() or similar functions. And maybe open a bug report with the findings here.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              T 1 Reply Last reply
              0
              • T TheLumbee

                @JonB @J-Hilk @DerReisende Thanks for all the responses! Didn't actually expect much here. I apologize for not providing more details. I've been dealing with this file parsing issue in C++ for years. Same code in Windows takes >100x times to complete rather than using Linux for some odd reason which I've posted in C++ forums prior to using Qt, but what you've provided is actually the first significant improvement I've ever seen.

                So thank you for that!

                I've tested this with versions 512, 5.15, 6.0, 6.2.4, and 6.4. Never noticed a major difference between them regarding this issue. Current machine: i7-6700 with 32GB RAM. So not sure what y'all are working with but the results seem promising.

                I was previously streaming into a QTextStream then reading line-by-line but came across this post: https://forum.qt.io/topic/98282/parsing-large-big-text-files-quickly and a couple of others that suggested that is more expensive that using a QByteArray. I didn't notice much difference to be quite honest.

                I did comment out the QDateTime parsing just to check and it was a significant improvement. Not quite like Rust but I'll attribute that to @JonB comment:

                That "naive" means it does not do any local time/daylight etc, conversions.
                

                If any of you are interested, I'll test each of your solutions and provide an update. But this actually woke me up and got me excited to start my day so thank you.

                D Offline
                D Offline
                DerReisende
                wrote on last edited by
                #29

                @TheLumbee said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                @JonB @J-Hilk @DerReisende Thanks for all the responses! Didn't actually expect much here. I apologize for not providing more details. I've been dealing with this file parsing issue in C++ for years. Same code in Windows takes >100x times to complete rather than using Linux for some odd reason which I've posted in C++ forums prior to using Qt, but what you've provided is actually the first significant improvement I've ever seen.

                Just tested my solution on windows 11 with VS 2022...
                My cached solution finishes in 19 seconds (compared to approx. 7 on macOS), the original version takes 575 seconds...OMG! Release mode with AVX2 enabled.

                T 1 Reply Last reply
                1
                • J.HilkJ J.Hilk

                  @TheLumbee said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                  f any of you are interested, I'll test each of your solutions and provide an update

                  sure, feedback is always appreciated! Nothing more discouraging than getting ghosted after providing an answer :D

                  But this actually woke me up and got me excited to start my day so thank you

                  👍 thumbsup

                  T Offline
                  T Offline
                  TheLumbee
                  wrote on last edited by
                  #30

                  @J-Hilk said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                  sure, feedback is always appreciated! Nothing more discouraging than getting ghosted after providing an answer :D

                  Thanks for the answer, but QStringRef is not available in Qt 6.4. Can't test this solution. Although I did replace with QString, but the performance was middling.

                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @TheLumbee said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                    Thanks for all the responses! Didn't actually expect much here.

                    Can't speak for other fora, but we are quality here in this forum :)

                    If any of you are interested, I'll test each of your solutions and provide an update.

                    Please do :) Note that mine will be least the code for the greatest speed benefit :) You get your money back if you don't think so ;-) Note that really the file reading, buffering etc. is marginal to the whole, the single most important thing is that QDateTime::fromString() is "unusably bad" for performance, unless you move to Qt 6.3+ and say it's a lot better there.

                    T Offline
                    T Offline
                    TheLumbee
                    wrote on last edited by TheLumbee
                    #31

                    @JonB said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                    @TheLumbee said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                    Please do :) Note that mine will be least the code for the greatest speed benefit :) You get your money back if you don't think so ;-) Note that really the file reading, buffering etc. is marginal to the whole, the single most important thing is that QDateTime::fromString() is "unusably bad" for performance, unless you move to Qt 6.3+ and say it's a lot better there.

                    Of all the solutions, this one has the best performance, for Qt at least. Results are around 3900ms. Still quite a bit slower than Rust. Issue is, I'm looking at parsing files 1GB+ in size so that really adds up when its 5x the time to complete.

                    1 Reply Last reply
                    0
                    • JoeCFDJ JoeCFD

                      Rust is made for quicker performance. Qt is made for HMI and speed is not the key feature.
                      If there are bottlenecks in your app, you can add Rust lib to handle them. If you know Rust well, the big banks will like to have you for high-speed trading apps. Rust is getting popular now and it is something: good to know.

                      T Offline
                      T Offline
                      TheLumbee
                      wrote on last edited by
                      #32

                      @JoeCFD said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                      Rust is made for quicker performance. Qt is made for HMI and speed is not the key feature.
                      If there are bottlenecks in your app, you can add Rust lib to handle them. If you know Rust well, the big banks will like to have you for high-speed trading apps. Rust is getting popular now and it is something: good to know.

                      I'm beginning to notice that. But I haven't even found a C/C++ implementation that competes, at least in this aspect alone, with what Rust is doing.

                      I am actually considering just creating a Rust lib to handle this. Not sure what other options I have if I'm looking to get this kind of performance. I know Rust well enough so let the big banks know I'm available ;-).

                      Given that I'm expecting much larger file sizes, using Rust would be the best choice I think. Maybe a solution will arise with C++ that can handle it.

                      1 Reply Last reply
                      0
                      • Christian EhrlicherC Christian Ehrlicher

                        @JonB said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                        nd the question is what to do from Qt to get acceptable performance regardless of the reasons?

                        compare rust with std::get_time() or similar functions. And maybe open a bug report with the findings here.

                        T Offline
                        T Offline
                        TheLumbee
                        wrote on last edited by
                        #33

                        @Christian-Ehrlicher said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                        @JonB said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                        nd the question is what to do from Qt to get acceptable performance regardless of the reasons?

                        compare rust with std::get_time() or similar functions. And maybe open a bug report with the findings here.

                        I'll try to get to this at some point. Just seems insane that the performance between Rust and C++ is so different when it comes to parsing these files.

                        Christian EhrlicherC 1 Reply Last reply
                        0
                        • D DerReisende

                          @TheLumbee said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                          @JonB @J-Hilk @DerReisende Thanks for all the responses! Didn't actually expect much here. I apologize for not providing more details. I've been dealing with this file parsing issue in C++ for years. Same code in Windows takes >100x times to complete rather than using Linux for some odd reason which I've posted in C++ forums prior to using Qt, but what you've provided is actually the first significant improvement I've ever seen.

                          Just tested my solution on windows 11 with VS 2022...
                          My cached solution finishes in 19 seconds (compared to approx. 7 on macOS), the original version takes 575 seconds...OMG! Release mode with AVX2 enabled.

                          T Offline
                          T Offline
                          TheLumbee
                          wrote on last edited by
                          #34

                          @DerReisende said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                          Just tested my solution on windows 11 with VS 2022...
                          My cached solution finishes in 19 seconds (compared to approx. 7 on macOS), the original version takes 575 seconds...OMG! Release mode with AVX2 enabled.

                          Yeah, there has to be something internally with the way Windows handles I/O for the massive difference. I've been trying to narrow down the issue for years without success. Interesting point though.

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            TheLumbee
                            wrote on last edited by
                            #35

                            One issue I'm facing is still QDateTime parsing. Even if I create the Rust lib, it doesn't have QDateTime and std::chrono interoperability. So I was thinking of returning a Tick array with a const char* for DateTime but then I'd still have to go through the entire Tick array and convert all the values to QDateTimes anyway. This sort of bring back the initial problems.

                            Honestly, this performance thing is the big reason I'm struggling to decide between this, https://github.com/fzyzcjy/flutter_rust_bridge, and Qt/QML for projects. I love Qt but performance is huge for me. Just looking for a justification here.

                            D JonBJ 2 Replies Last reply
                            0
                            • T TheLumbee

                              One issue I'm facing is still QDateTime parsing. Even if I create the Rust lib, it doesn't have QDateTime and std::chrono interoperability. So I was thinking of returning a Tick array with a const char* for DateTime but then I'd still have to go through the entire Tick array and convert all the values to QDateTimes anyway. This sort of bring back the initial problems.

                              Honestly, this performance thing is the big reason I'm struggling to decide between this, https://github.com/fzyzcjy/flutter_rust_bridge, and Qt/QML for projects. I love Qt but performance is huge for me. Just looking for a justification here.

                              D Offline
                              D Offline
                              DerReisende
                              wrote on last edited by
                              #36

                              @TheLumbee Why don't you just parse the date string in a rust function which returns the number of msecs sinc midnight 1970? This way you only have to store a qint64 variable. If you need a QDateTime instance then just call QDateTime::fromMSecsSinceEpoch when needed. This should be fast.

                              T 1 Reply Last reply
                              0
                              • D DerReisende

                                @TheLumbee Why don't you just parse the date string in a rust function which returns the number of msecs sinc midnight 1970? This way you only have to store a qint64 variable. If you need a QDateTime instance then just call QDateTime::fromMSecsSinceEpoch when needed. This should be fast.

                                T Offline
                                T Offline
                                TheLumbee
                                wrote on last edited by
                                #37

                                @DerReisende said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                @TheLumbee Why don't you just parse the date string in a rust function which returns the number of msecs sinc midnight 1970? This way you only have to store a qint64 variable. If you need a QDateTime instance then just call QDateTime::fromMSecsSinceEpoch when needed. This should be fast.

                                Don't know why I didn't think of that. I'll write the Rust lib, and hopefully have some great results. I'll let you know.

                                1 Reply Last reply
                                0
                                • T TheLumbee

                                  @Christian-Ehrlicher said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                  @JonB said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                  nd the question is what to do from Qt to get acceptable performance regardless of the reasons?

                                  compare rust with std::get_time() or similar functions. And maybe open a bug report with the findings here.

                                  I'll try to get to this at some point. Just seems insane that the performance between Rust and C++ is so different when it comes to parsing these files.

                                  Christian EhrlicherC Online
                                  Christian EhrlicherC Online
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #38

                                  @TheLumbee said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                  Just seems insane that the performance between Rust and C++ is so different when it comes to parsing these files.

                                  Simply read my explanation on what needs to be done when parsing a datetime string. This can be optimized in Qt but if someone needs speed other solutions are much better (see @J-Hilk 's solution by bypassing QDateTime::fromString() at all) so noone is doing it.

                                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                  Visit the Qt Academy at https://academy.qt.io/catalog

                                  1 Reply Last reply
                                  0
                                  • T TheLumbee

                                    One issue I'm facing is still QDateTime parsing. Even if I create the Rust lib, it doesn't have QDateTime and std::chrono interoperability. So I was thinking of returning a Tick array with a const char* for DateTime but then I'd still have to go through the entire Tick array and convert all the values to QDateTimes anyway. This sort of bring back the initial problems.

                                    Honestly, this performance thing is the big reason I'm struggling to decide between this, https://github.com/fzyzcjy/flutter_rust_bridge, and Qt/QML for projects. I love Qt but performance is huge for me. Just looking for a justification here.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by
                                    #39

                                    @TheLumbee
                                    From where you are now. If you comment out the datetime handling in the C++ (and the Rust if you like), is your performance timing for the Qt/C++ acceptable compared to the Rust? So it is only the QDateTime parsing which is the issue for you?

                                    T 1 Reply Last reply
                                    0
                                    • J.HilkJ J.Hilk

                                      @JonB said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                      I doubt this is significant

                                      it is, depending on Qt Version, if 5.15 than yes, using splitRef should be significantly faster. Not sure if they optimised split in Qt6 or simply dropped splitRef because hardly any one used it 🤷‍♂️

                                      Christian EhrlicherC Online
                                      Christian EhrlicherC Online
                                      Christian Ehrlicher
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #40

                                      @J-Hilk said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                      Not sure if they optimised split in Qt6 or simply dropped splitRef because hardly any one used it 🤷‍♂️

                                      QStringRef is gone and so is splitRef().
                                      You should use QStringView and it's split() version.

                                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                      Visit the Qt Academy at https://academy.qt.io/catalog

                                      1 Reply Last reply
                                      0
                                      • D Offline
                                        D Offline
                                        DerReisende
                                        wrote on last edited by
                                        #41

                                        Here is a version of @J-Hilk 's program modified to run with Qt 6.4:

                                        int main(int argc, char **argv) {
                                            QFile *testFile = new QFile(R"(C:\Users\aea_t\Downloads\TestFile.txt)");
                                        
                                        
                                            testFile->open(QFile::ReadOnly);
                                            Instrument instr;
                                            Tick t;
                                        
                                            QElapsedTimer *parseTimer2 = new QElapsedTimer();
                                            parseTimer2->start();
                                            testFile->reset();
                                            instr.tickList.reserve(1000000);
                                        
                                            auto DateTimeParser = [](const QStringView string) -> QDateTime {
                                                const QDate date(string.left(4).toInt(), string.mid(4, 2).toInt(), string.mid(6, 2).toInt());
                                                const QTime time(string.mid(9, 2).toInt(), string.mid(11, 2).toInt(), string.mid(13, 2).toInt(),
                                                                 string.mid(15, 3).toInt());
                                                QDateTime dt(date, time);
                                                return dt;
                                            };
                                        
                                            QTextStream readFile(testFile);
                                            QString line;
                                            line.reserve(100);
                                            const QChar semicolon(';');
                                            while (!readFile.atEnd()) {
                                                if (!readFile.readLineInto(&line, 100)) {
                                                    break;
                                                }
                                                const auto result = line.split(semicolon);
                                                instr.tickList.append(
                                                        {DateTimeParser(result.at(0)), result.at(1).toFloat(), result.at(2).toFloat(), result.at(3).toFloat(),
                                                         result.at(3).toUInt()});
                                            }
                                            qDebug().noquote() << QString("Qt parse time: %1ms")
                                                    .arg(parseTimer2->elapsed());
                                        }
                                        

                                        Before we continue complaining about Qt it would be great to know on what OS @TheLumbee is running the code?
                                        All solution seem to run much slower on Windows than Linux and macOS.
                                        I tried the above version on my Win 11 machine VS2022 and it takes around 32 seconds to complete (compared to his 1.4 seconds on macOS). I don't have a mingw installation for comparison unfortunately :(

                                        Christian EhrlicherC T 2 Replies Last reply
                                        0
                                        • D DerReisende

                                          Here is a version of @J-Hilk 's program modified to run with Qt 6.4:

                                          int main(int argc, char **argv) {
                                              QFile *testFile = new QFile(R"(C:\Users\aea_t\Downloads\TestFile.txt)");
                                          
                                          
                                              testFile->open(QFile::ReadOnly);
                                              Instrument instr;
                                              Tick t;
                                          
                                              QElapsedTimer *parseTimer2 = new QElapsedTimer();
                                              parseTimer2->start();
                                              testFile->reset();
                                              instr.tickList.reserve(1000000);
                                          
                                              auto DateTimeParser = [](const QStringView string) -> QDateTime {
                                                  const QDate date(string.left(4).toInt(), string.mid(4, 2).toInt(), string.mid(6, 2).toInt());
                                                  const QTime time(string.mid(9, 2).toInt(), string.mid(11, 2).toInt(), string.mid(13, 2).toInt(),
                                                                   string.mid(15, 3).toInt());
                                                  QDateTime dt(date, time);
                                                  return dt;
                                              };
                                          
                                              QTextStream readFile(testFile);
                                              QString line;
                                              line.reserve(100);
                                              const QChar semicolon(';');
                                              while (!readFile.atEnd()) {
                                                  if (!readFile.readLineInto(&line, 100)) {
                                                      break;
                                                  }
                                                  const auto result = line.split(semicolon);
                                                  instr.tickList.append(
                                                          {DateTimeParser(result.at(0)), result.at(1).toFloat(), result.at(2).toFloat(), result.at(3).toFloat(),
                                                           result.at(3).toUInt()});
                                              }
                                              qDebug().noquote() << QString("Qt parse time: %1ms")
                                                      .arg(parseTimer2->elapsed());
                                          }
                                          

                                          Before we continue complaining about Qt it would be great to know on what OS @TheLumbee is running the code?
                                          All solution seem to run much slower on Windows than Linux and macOS.
                                          I tried the above version on my Win 11 machine VS2022 and it takes around 32 seconds to complete (compared to his 1.4 seconds on macOS). I don't have a mingw installation for comparison unfortunately :(

                                          Christian EhrlicherC Online
                                          Christian EhrlicherC Online
                                          Christian Ehrlicher
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #42

                                          @DerReisende said in Rust file parsing significantly faster than Qt/C++ file parsing. Solutions for Qt implementation wanted. File size: 68.5 MB:

                                          const auto result = line.split(semicolon);

                                          Please read my last post about QStringView

                                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                          Visit the Qt Academy at https://academy.qt.io/catalog

                                          D 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