[Development] QtCS 2017 QtCore sessions

Marc Mutz marc.mutz at kdab.com
Fri Dec 1 10:31:18 CET 2017


On 2017-11-30 22:13, Thiago Macieira wrote:
> 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?

The spaceship operator solves the problem for qCompareStrings(). One 
could say we already have all relational operators for all combinations 
of string-like objects to solve it for the user _now_, but 
qCompareStrings(), like operator<=>() return the full information, while 
relational operators only return a subset. You know that, I know. I'm 
just mentioning it for completeness sake.

And we have more than qCompareStrings(). How does operator<=> help with 
qFindString()/qIndexOf() (which is still missing)? Answer: it doesn't. 
There's no infix notation for find-in-string. And there probably never 
will be (fancy proposing operator=~, anyone?).

[...]
>> 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

Ah, but you said that the flaw was in the _standard_. But what you show 
are sub-optimal compiler implementations. There's nothing in the 
standard that prevents a compiler to implement char_traits::length() as 
a compiler intrinsic that can have different backends for constexpr and 
runtime evaluation.

So, would the following be acceptable:

1. QSV uses char_traits<char16_t>::length() to calculate the length 
(that was my initial implementation, but it's constexpr only starting 
with C++17). Then QSV(Char*) is only constexpr in C++17. I can live with 
that.
2. You/Intel work on the compiler vendors to get 
char_traits<char16_t>::length() implemented as an intrinsic, with SIMD 
at runtime and compiler magic at compile-time?

Then we fix the problem where it should be fixed, and just piggy-back on 
the more general solution. And it's easy to sell to QSV users why that 
ctor is not constexpr until C++17 (and we don't even need any #ifdefery 
in the implementation).

What do you think?

Thanks,
Marc


That is, unless compiler vendors haven't yet done this already.





More information about the Development mailing list