@@ -822,6 +822,40 @@ NO_INLINE static void _jswrap_array_sort(JsvIterator *head, int n, JsVar *compar
822822
823823 JsvIterator pivot ;
824824 jsvIteratorClone (& pivot , head );
825+ #ifndef SAVE_ON_FLASH
826+ if (n > 16 ) {
827+ /* if we have enough elements where using the wrong pivot may be a problem, try a median of 3
828+ to find the best pivot - this can be slower as we have to iterate over all the items in the list */
829+ int midIndex = n >>1 ;
830+ JsvIterator mid ;
831+ jsvIteratorClone (& mid , head );
832+ for (int i = 0 ; i < midIndex ; i ++ ) jsvIteratorNext (& mid );
833+ JsvIterator high ;
834+ jsvIteratorClone (& high , & mid );
835+ for (int i = midIndex ; i < n - 1 ; i ++ ) jsvIteratorNext (& high );
836+
837+ JsVar * lowValue = jsvIteratorGetValue (& pivot );
838+ JsVar * midValue = jsvIteratorGetValue (& mid );
839+ JsVar * highValue = jsvIteratorGetValue (& high );
840+
841+ // now find the median of these three values
842+ JsVarInt lowMid = _jswrap_array_sort_compare (lowValue , midValue , compareFn );
843+ JsVarInt midHigh = _jswrap_array_sort_compare (midValue , highValue , compareFn );
844+ JsVarInt lowHigh = _jswrap_array_sort_compare (lowValue , highValue , compareFn );
845+ if ((lowMid <=0 && midHigh <=0 ) || (lowHigh <=0 && midHigh >=0 )) {
846+ // mid is median
847+ jsvIteratorSetValue (& pivot , midValue );
848+ jsvIteratorSetValue (& mid , lowValue );
849+ } else if ((lowMid >=0 && lowHigh <=0 ) || (midHigh >=0 && lowHigh >=0 )) {
850+ // high is median
851+ jsvIteratorSetValue (& pivot , highValue );
852+ jsvIteratorSetValue (& high , lowValue );
853+ } // else low is median, do nothing
854+ jsvUnLock3 (lowValue , midValue , highValue );
855+ jsvIteratorFree (& mid );
856+ jsvIteratorFree (& high );
857+ }
858+ #endif
825859 bool pivotLowest = true; // is the pivot the lowest value in here?
826860 JsVar * pivotValue = jsvIteratorGetValue (& pivot );
827861 /* We're just going to use the first entry (head) as the pivot...
@@ -830,7 +864,7 @@ NO_INLINE static void _jswrap_array_sort(JsvIterator *head, int n, JsVar *compar
830864
831865 int nlo = 0 , nhigh = 0 ;
832866 JsvIterator it ;
833- jsvIteratorClone (& it , head ); //
867+ jsvIteratorClone (& it , head );
834868 jsvIteratorNext (& it );
835869
836870
0 commit comments