Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the three-way comparison operator always efficient?

Herb Sutter, in his proposal for the "spaceship" operator (section 2.2.2, bottom of page 12), says:

Basing everything on <=> and its return type: This model has major advantages, some unique to this proposal compared to previous proposals for C++ and the capabilities of other languages:

[...]

(6) Efficiency, including finally achieving zero-overhead abstraction for comparisons: The vast majority of comparisons are always single-pass. The only exception is generated <= and >= in the case of types that support both partial ordering and equality. For <, single-pass is essential to achieve the zero-overhead principle to avoid repeating equality comparisons, such as for struct Employee { string name; /*more members*/ }; used in struct Outer { Employeee; /*more members*/ }; – today’s comparisons violates zero-overhead abstraction because operator< on Outer performs redundant equality comparisons, because it performs if (e != that.e) return e < that.e; which traverses the equal prefix of e.name twice (and if the name is equal, traverses the equal prefixes of other members of Employee twice as well), and this cannot be optimized away in general. As Kamiński notes, zero-overhead abstraction is a pillar of C++, and achieving it for comparisons for the first time is a significant advantage of this design based on <=>.

But then he gives this example (section 1.4.5, page 6):

class PersonInFamilyTree { // ... public:   std::partial_ordering operator<=>(const PersonInFamilyTree& that) const {     if (this->is_the_same_person_as ( that)) return partial_ordering::equivalent;     if (this->is_transitive_child_of( that)) return partial_ordering::less;     if (that. is_transitive_child_of(*this)) return partial_ordering::greater;     return partial_ordering::unordered;   }   // ... other functions, but no other comparisons ... }; 

Would define operator>(a,b) as a<=>b > 0 not lead to large overhead? (though in a different form than he discusses). That code would first test for equality, then for less, and finally for greater, rather than only and directly testing for greater.

Am I missing something here?

like image 489
Cris Luengo Avatar asked Jan 02 '18 18:01

Cris Luengo


People also ask

What is the === comparison operator used for?

Equal to ( === ) — returns true if the value on the left is equal to the value on the right, otherwise it returns false .

Why are comparison operators important in programming?

Comparison operators are used in conditional expressions to determine if one block of code or another executes, thus controlling flow in a computer program. They thereby support complex decision making in computer programs.

Is a comparison operator used for non equality?

Equality operators: == and != The binary equality operators compare their operands for strict equality or inequality. The equality operators, equal to ( == ) and not equal to ( != ), have lower precedence than the relational operators, but they behave similarly. The result type for these operators is bool .


1 Answers

Would define operator>(a,b) as a<=>b > 0 not lead to large overhead?

It would lead to some overhead. The magnitude of the overhead is relative, though - in situations when costs of running comparisons are negligible in relation to the rest of the program, reducing code duplication by implementing one operator instead of five may be an acceptable trade-off.

However, the proposal does not suggest removing other comparison operators in favor of <=>: if you want to overload other comparison operators, you are free to do it:

Be general: Don’t restrict what is inherent. Don’t arbitrarily restrict a complete set of uses. Avoid special cases and partial features. – For example, this paper supports all seven comparison operators and operations, including adding three-way comparison via <=>. It also supports all five major comparison categories, including partial orders.

like image 124
Sergey Kalinichenko Avatar answered Sep 24 '22 09:09

Sergey Kalinichenko