Opinions: The Best and Worst of D (for a lecture/talk I intend to give)
Dominikus Dittes Scherkl via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Jul 9 10:43:15 PDT 2014
On Wednesday, 9 July 2014 at 17:13:21 UTC, H. S. Teoh via
Digitalmars-d-learn wrote:
> On Wed, Jul 09, 2014 at 04:24:38PM +0000, Dominikus Dittes
> Scherkl via Digitalmars-d-learn wrote:
>> /// Returns -1 if a < b, 0 if they are equal or 1 if a > b.
>> /// this will always yield a correct result, no matter which
>> numeric types are compared.
>> /// It uses one extra comparison operation if and only if
>> /// one type is signed and the other unsigned but the signed
>> value is >= 0
>> /// (that is what you need to pay for stupid choice of type).
> [...]
>
> Yeah, I don't see what's the problem with comparing signed and
> unsigned
> values, as long as the result is as expected. Currently,
> however, this
> code asserts, which is wrong:
>
> uint x = uint.max;
> int y = -1;
> assert(x > y);
Yes, this is really bad.
But last time I got the response that this is so to be compatible
with C.
That is what I really thought was the reason why D throw away
balast from C,
to fix bugs.
>> static if(Unqual!T == Unqual!U)
>
> Nitpick: should be:
>
> static if(is(Unqual!T == Unqual!U))
Of course.
> [...]
>> else static if(isSigned!T && isUnsigned!U)
>> {
>> alias CommonType!(Unsigned!T, U) C;
>> return (a < 0) ? -1 : opCmp!(cast(C)a, cast(C)b);
>> }
>> else static if(isUnsigned!T && isSigned!U)
>> {
>> alias CommonType!(T, Unsigned!U) C;
>> return (b < 0) ? 1 : opCmp!(cast(C)a, cast(C)b);
>> }
> [...]
>
> Hmm. I wonder if there's a more efficient way to do this.
I'm sure. But I think it should be done at the compiler, not in a
library.
> {...]
> opCmp is just a single sub instruction (this is why opCmp is
> defined the
> way it is, BTW), whereas the "smart" signed/unsigned comparison
> is 4
> instructions long.
> [...]
> you can see, the branched version is 5 instructions long, and
> always
> causes a CPU pipeline hazard.
>
> So I submit that the unbranched version is better. ;-)
I don't think so, because the branch will only be taken if the
signed
type is >= 0 (in fact unsigned). So if the signed/unsigned
comparison
is by accident, you pay the extra runtime. But if it is
intentional
the signed value is likely to be negative, so you get a correct
result
with no extra cost.
Even better for constants, where the compiler can not only
evaluate expressions like (uint.max > -1) correct, but it should
optimize them completely away!
>
> (So much for premature optimization... now lemme go and actually
> benchmark this stuff and see how well it actually performs in
> practice.
Yes, we should do this.
> Often, such kinds of hacks often perform more poorly than
> expected due
> to unforeseen complications with today's complex CPU's. So for
> all I
> know, I could've just been spouting nonsense above. :P)
I don't see such a compiler change as a hack. It is a strong
improvement IMHO.
More information about the Digitalmars-d-learn
mailing list