(svn r13276) -Codechange: use qsort() for initial sorting of a list for better performance (credits go to skidd13 and peter1138)
This commit is contained in:
		| @@ -9,11 +9,12 @@ | ||||
| #include "date_type.h" | ||||
|  | ||||
| enum SortListFlags { | ||||
| 	VL_NONE    = 0,      ///< no sort | ||||
| 	VL_DESC    = 1 << 0, ///< sort descending or ascending | ||||
| 	VL_RESORT  = 1 << 1, ///< instruct the code to resort the list in the next loop | ||||
| 	VL_REBUILD = 1 << 2, ///< create sort-listing to use for qsort and friends | ||||
| 	VL_END     = 1 << 3, | ||||
| 	VL_NONE       = 0,      ///< no sort | ||||
| 	VL_DESC       = 1 << 0, ///< sort descending or ascending | ||||
| 	VL_RESORT     = 1 << 1, ///< instruct the code to resort the list in the next loop | ||||
| 	VL_REBUILD    = 1 << 2, ///< rebuild the sort list | ||||
| 	VL_FIRST_SORT = 1 << 3, ///< sort with qsort first | ||||
| 	VL_END        = 1 << 4, | ||||
| }; | ||||
| DECLARE_ENUM_AS_BIT_SET(SortListFlags); | ||||
|  | ||||
| @@ -52,10 +53,25 @@ public: // Temporary: public for conversion only | ||||
| 		this->resort_timer = DAY_TICKS * 10; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Reverse the list | ||||
| 	 */ | ||||
| 	void Reverse() | ||||
| 	{ | ||||
| 		assert(this->IsSortable()); | ||||
|  | ||||
| 		T *a = this->data; | ||||
| 		T *b = a + (this->items - 1); | ||||
|  | ||||
| 		do { | ||||
| 			Swap(*a, *b); | ||||
| 		} while (((a + 1) != b) && (++a != --b)); | ||||
| 	} | ||||
|  | ||||
| public: | ||||
| 	GUIList() : | ||||
| 		func_list(NULL), | ||||
| 		flags(VL_NONE), | ||||
| 		flags(VL_FIRST_SORT), | ||||
| 		sort_type(0), | ||||
| 		resort_timer(1) | ||||
| 	{}; | ||||
| @@ -78,7 +94,7 @@ public: | ||||
| 	void SetSortType(uint8 n_type) | ||||
| 	{ | ||||
| 		if (this->sort_type != n_type) { | ||||
| 			SETBITS(this->flags, VL_RESORT); | ||||
| 			SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT); | ||||
| 			this->sort_type = n_type; | ||||
| 		} | ||||
| 	} | ||||
| @@ -110,6 +126,8 @@ public: | ||||
| 			CLRBITS(this->flags, VL_DESC); | ||||
| 		} | ||||
| 		this->sort_type = l.criteria; | ||||
|  | ||||
| 		SETBITS(this->flags, VL_FIRST_SORT); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -158,21 +176,16 @@ public: | ||||
| 	{ | ||||
| 		this->flags ^= VL_DESC; | ||||
|  | ||||
| 		if (this->IsSortable()) { | ||||
| 			T *a = this->data; | ||||
| 			T *b = a + (this->items - 1); | ||||
|  | ||||
| 			do { | ||||
| 				Swap(*a, *b); | ||||
| 			} while (((a + 1) != b) && (++a != --b)); | ||||
| 		} | ||||
| 		if (this->IsSortable()) this->Reverse(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * GnomeSort algorithm | ||||
| 	 *  This sorting uses a slightly modifyied Gnome search. | ||||
| 	 *  The basic Gnome search trys to sort already sorted | ||||
| 	 *  list parts. The modification skips these. | ||||
| 	 *  list parts. The modification skips these. For the first | ||||
| 	 *  sorting we use qsort since it is faster for irregular | ||||
| 	 *  sorted data. | ||||
| 	 * | ||||
| 	 * @param compare The function to compare two list items | ||||
| 	 * */ | ||||
| @@ -188,12 +201,20 @@ public: | ||||
| 		/* Do not sort when the list is not sortable */ | ||||
| 		if (!this->IsSortable()) return; | ||||
|  | ||||
| 		const bool desc = HASBITS(this->flags, VL_DESC); | ||||
|  | ||||
| 		if (HASBITS(this->flags, VL_FIRST_SORT)) { | ||||
| 			qsort(this->data, this->items, sizeof(T), (int (*)(const void *a, const void *b))compare); | ||||
|  | ||||
| 			if (desc) this->Reverse(); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		T *a = this->data; | ||||
| 		T *b = a + 1; | ||||
|  | ||||
| 		uint length = this->items; | ||||
| 		uint offset = 0; // Jump variable | ||||
| 		const bool desc = HASBITS(this->flags, VL_DESC); | ||||
|  | ||||
| 		while (length > 1) { | ||||
| 			const int diff = compare(a, b); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 smatz
					smatz