[Development] RFC: Proposal for a semi-radical change in Qt APIs taking strings

Marc Mutz marc.mutz at kdab.com
Sat Oct 17 01:18:06 CEST 2015


Kurt,

The mail you're replying to has nothing to do with QStringView. It was a 
tangent about std::string_view.

If you need a real-world example of where QStringView would be handy: Some 
3rd-party code returns you a char16_t *path, and you want to perform a 
QDir::cd(). Currently, you need to create a QString (which allocates). Had 
QDir::cd() taken a QStringView, you wouldn't have that allocation.

Another example I already mentioned:

> E.g. local QStrings could be replaced by QVarLengthArray<QChar>,
> 
> e.g. in code like this:
>     QString joinstr = QLatin1String("\"\n");
>     joinstr += indent;
>     joinstr += indent;
>     joinstr += QLatin1Char('"');
>     
>     QString rc(QLatin1Char('"'));
>     rc += result.join(joinstr);
>     rc += QLatin1Char('"');
> 
> Even when replaced with QStringBuilder:
>     QString joinstr = QLatin1String("\"\n") + indent + indent
>     
>                        + QLatin1Char('"');
>     
>     QString rc = QLatin1Char('"') + result.join(joinstr) +
>     QLatin1Char('"');
> 
> But the main benefit would be that we only ever need one overload for a
> QString-taking function, not N, N > 3.

Final with QStringView (and a minor modification to QStringBuilder):

  QVarLengthArray<QChar> joinstr // doesn't alloc (for most 'indent's)
      = QLatin1String("\"\n") + indent + indent + QLatin1Char('"');

  // in this line, QStringList::join() doesn't know about QVarLengthArray.
  // but it takes a QStringView and therefore transparently accepts QVLA
  QString rc = QLatin1Char('"') + result.join(joinstr) + QLatin1Char('"');

Please understand my POV: I am of the firm belief that Qt has no business 
creating inefficiencies for its users by sloppy implementation. Anywhere. We 
cannot know whether one user is calling QString::multiArg() in a tight loop. 
It might be dominating her runtime. 99.9% of users probably couldn't care less 
about QString::multiArg() performance. But we need to care about the 0.1%, 
because that number is much closer to 100% if you integrate it over all users' 
critical paths (iow: every Qt user will have *some* part of Qt that she wished 
was faster, heck, iirc KMail ran into QObject::connect as a bottleneck at some 
point in the past!).

The inefficiencies I (and Sergio and Milian and, I'm happy to see, Friedemann, 
and others) care about are not ones you will find in a profiler in those 99.9% 
of cases, because they are not used in a critical path. But even for the 99.9% 
of users, if we make all of Qt 10% faster on average, their apps will run 
close to 10% faster, too. Automatically.

So yes, I care about performance. I find it intolerable that todays software 
takes 1000x the memory, 1000x the CPU capacity and doesn't get a given jobs 
done in less wallclock time than software 20 years ago. And people don't use 
C++ because it's pretty. You cannot compete with Java on programmer efficiency. 
Its standard library is orders of magnitude larger than C++'s. People choose 
C++ (and accept the associated loss in programmer efficiency), because they 
require the bare metal efficiency of C++. And if Qt gets in the way, they will 
look for alternatives and find them in places that make Qt look like paradise.

That said, QStringView is as much about

- slim interface type vs. thick, fat, storage type
- interop with 3rd-party and native code

than it is about efficiency.

Bottomline: I don't need a fancy anylysis to tell me that less allocations = 
faster programs = more happy Qt users.

And please don't forget that QString fanboys can continue to massacre the heap 
if they so wish. After all, we've had QStringRef for a long time now, but most 
people still write str.mid(n).toInt() instead of str.midRef().toInt(). 
QStringView won't change that: A function taking QStringView accepts a 
QString, too (either by implicit conversion, or where it makes sence, by 
QString overload).

Thanks,
Marc

On Friday 16 October 2015 21:42:23 Kurt Pattyn wrote:
> Marc,
> 
> It is clear that your main concern is performance (needless conversions)
> and convenience (being able to work efficiently with 3rd party libraries).
> Regarding performance, I think it would be good if we could come up with
> some numbers. How 'bad' is the current implementation compared to an
> 'ideal' situation? And then define some acceptable target keeping into
> account convenience. Otherwise I am afraid that discussions can keep going
> forever over 1 instruction more or less. Regarding convenience, and that
> is what Qt is all about, I think you made a tremendous proposal that can
> really bring Qt a big step forward. The idea is very sound and clear. Of
> course, there are technical challenges, but that is what we are supposed
> to solve.
> 
> I also agree that we should aim for simplicity. QString and QStringView is
> simple to understand, iff we can get rid of all other string related
> classes. The ideal case would be just to have one QString class, although
> I doubt that is achievable.
> 
> I think it would be good to come up with some real-world use-cases that
> show how a Qt user and a Qt application could benefit from your proposal.
> Personally, I never experienced a performance problem with QString; but
> then the applications I write are not very string oriented. I am a QString
> aficionado :-)
> 
> After all, what I really like about Qt is convenience, simplicity and
> portability. I think this should be the main focus of Qt, and that also
> implies smooth collaboration with the outside world.
> 
> Cheers,
> 
> Kurt
> 
> > On 16 Oct 2015, at 21:47, Marc Mutz <marc.mutz at kdab.com> wrote:
> >> On Friday 16 October 2015 19:31:50 Thiago Macieira wrote:
> >> The conversion from one to the other is one instruction.
> > 
> > Which is one instruction too much for tail-call optimisation, e.g.
> > 
> > But the point was about std::string_view binary compatibility. As
> > basically a C struct with no ownership semantics, it would be a perfect
> > vehicle to pass strings around different programming languages and
> > compilers, but only if the ABI (ie. the data members) were specified.

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt Experts



More information about the Development mailing list