How to override opCmp when two different sorts are needed?

Deewiant deewiant.doesnotlike.spam at gmail.com
Wed Aug 15 02:52:59 PDT 2007


Regan Heath wrote:
> C. Dunn wrote:
>> It's not just a matter of elegance.  C++ std::sort() is way, way
>> faster than qsort in cstdlib because the comparison function gets
>> inlined.  Sorting is one place where inlining is critical.
> 
> I believe the intention for D is that the optimizer will automagically
> inline everything it can.
> 

I'd imagine it's quite hard to inline a delegate or function pointer. In any
case, the current optimizer is a joke in many ways.

Functions, on the other hand, can be inlined, which is why std::sort and D's
built-in sort beat C's qsort (assuming they use approximately the same
algorithm): they're hard-coded to use "a < b", which is either a "cmp" x86
instruction or an inlineable call to a.opCmp(b) which usually translates to "int
< int" and thus a "cmp" anyway.

This is why I recently suggested
(http://www.dsource.org/projects/tango/ticket/571) that Tango provide for
something like:

enum Dir : bool { Ascending, Descending }

// I forget the correct syntax, sorry if this is wrong
template sort(T, Dir D = Dir.Ascending) {
	bool compare(T a, T b) {
		static if (D == Dir.Ascending)
			return a < b;
		else
			return a > b;
	}
	
	void sort(T[] a) {
		// sort using compare for comparing
	}
}

This allows the user to choose whether to sort in ascending or descending order,
and improves speed noticeably. Currently Tango uses a functor struct:

struct IsLess(T) {
	bool opCall(T a, T b) {
		return a < b;
	}
}

Which is not inlined. A "call" instruction is generated for every comparison.

-- 
Remove ".doesnotlike.spam" from the mail address.



More information about the Digitalmars-d mailing list