[Development] QtCS 2017 QtCore sessions

Thiago Macieira thiago.macieira at intel.com
Thu Nov 30 22:13:38 CET 2017


On Thursday, 30 November 2017 12:08:45 PST Marc Mutz wrote:
> Don't go off on a tangent here. I used concepts syntax to keep the
> example simple. I can post with std::enable_if, if you prefer :)

Fair enough, I had not considered that.

> Anyway, the point is the asymmetry of member functions.
> u"Hello".compare(string) does not compile in C++ (it does in Java), so
> everyone that wants to write a template like the op== above will have to
> re-invent qCompareStrings(). The Qt API rules stipulate that the common
> use case should be made simple (we do, we have member functions
> whereever we can add them), but make the rest possible. And that's where
> qCompareStrings() come in. It makes the remaining 5% (random number)
> possible.

Why does anyone besides us need to write the op== like above? We have access 
to QtPrivate::qCompareStrings, so we can write the comparisons to our string 
objects.

Once those operator<=> are there, what benefit is there in having the API 
public and documented?

> >> IMNSHO, absent proof to the contrary, you are optimizing an edge case
> >> here, an edge case that people can easily fix by using
> >> 
> >>     auto s = QStringView{s, qustrlen(s)};
> >> 
> >> manually when they expect large strings. The missing constexpr is not
> >> so
> >> easily obtained than the SIMD length calculation.
> > 
> > This was a judgement call. The C++ standard needs to be fixed, so I am
> > doing
> > what I think is the correct direction: performance first.
> 
> And I would interpret the Qt API design rules differently: like
> qCompareStrings(), constexpr QSV ctors enable the remaining 5% of
> use-cases. If the standard equivalent wasn't constexpr all-over, one
> could maintain that what people don't know they will not miss. But
> std::string_view _is_ all-constexpr, and therefore (some) people will
> miss it.

Again, flaw in the standard. I do not feel we need to agree with the standard 
when it's flawed.

I'll happily add constexprness back when I'm allowed to have my cake and eat 
it too.

> That leaves the question whether long raw strings passed to
> QSV(Char*) without also passing the length are the common use-case or
> whether the common use-case is that the user doesn't care. And I think
> that it's the latter, because off the top of my head, I can think of no
> situation where I actually would need the length calculation in QSV's
> ctor. The situation is a bit different in std::string_view where this
> ctor also receives all C string literals. We have a separate ctor for
> that in QSV, so we don't depend so existentially on the (Char*) ctor to
> be constexpr, but we also don't have a performance problem, since the
> frequency of calls to that ctor is very, very low. And there's the
> work-around to enable the 10% (random number) of users that see a
> performance problem with that ctor to call qustrlen() manually.

I'd say that calling qustrlen manually is even more surprising and no one 
would think of doing that. Not even after finding that there's a bit of 
performance they could gain. Everyone just expects the constructor to 
calculate the length by itself.

> > API parallelism with the Standard Library is not required where the
> > standard
> > library makes mistakes. Requiring constexpr for calculating string
> > lengths is
> > one where I think it made a mistake. Therefore, I will not accept that
> > as an
> > argument.
> 
> We all think we're smarter than the committee, yes. Maybe we are, but
> swarm intelligence suggests otherwise.

To be clear: there's nothing wrong with adding constexpr where we can. 
Constexpr string literals make a lot of sense.

The flaw is in doing that in detriment to performance at runtime. EVERY SINGLE 
strlen function is SIMD-optimised, sometimes even multiple versions. There's 
even a dedicated instruction added to SSE4.2 to do that, plus the original 
8086 way (rep scasb) which was slow for a long time and now is fast again.

I don't have the benchmarks to prove it, but my gut feeling is that the SIMD 
code becomes worth it very quickly (despite the call overhead), sometime 
between 8 and 16 characters in the string.

https://godbolt.org/g/gBMykD

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list