Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-81311

Optimize QStringLiteral with constexpr

    XMLWordPrintable

Details

    • Suggestion
    • Resolution: Won't Do
    • Not Evaluated
    • None
    • None
    • None

    Description

      Simply adding a Q_DECL_CONSTEXPR inside QStringLiteral definition like this:

      #define QStringLiteral(str) \
          ([]() Q_DECL_NOEXCEPT -> QString { \
              enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
              static const Q_DECL_CONSTEXPR QStaticStringData<Size> qstring_literal = { \
                  Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \
                  QT_UNICODE_LITERAL(str) }; \
              QStringDataPtr holder = { qstring_literal.data_ptr() }; \
              const QString qstring_literal_temp(holder); \
              return qstring_literal_temp; \
          }()) \
          /**/
      

      works fine and heavily reduces binary size at least for MSVC compiler (checked on msvc2017 for x86 with /O2 optimization). I use Qt 5.12.6 and as I see on github - in newer versions nothing has changed.

      More brave optimization could be following (though this is pretty hacky and I may be missing something, please correct me in such case):

      #define QStringLiteral(str_value) \
          ([]() Q_DECL_NOEXCEPT -> const QString& { \
              enum { Size = sizeof(QT_UNICODE_LITERAL(str_value))/2 - 1 }; \
              static const Q_DECL_CONSTEXPR QStaticStringData<Size> qstring_literal = { \
                  Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \
                  QT_UNICODE_LITERAL(str_value) }; \
              static const QStringData* ptr = static_cast<const QStringData*>(&qstring_literal.str); \
              return *reinterpret_cast<const QString*>(&ptr); \
          }())
      

      this somewhat unwraps existing conversions and allows returning QString by reference which is more optimal in most use-cases, as most functions accept a const reference to QString. When QString is returned by value but receiver accepts reference - redundant temporary object is created, thus extra destrucor call, extra exception-handler code is generated, extra performance degradation (though very minor). This version reduces my project binary even more.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            thiago Thiago Macieira
            nonoum Evgeniy Evstratov
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes