This is just the F# version of the Java implementation of the dual quicksort algorithm as published on http://gdtoolbox.com/DualPivotQuicksort.pdf which is claimed to be 20% faster than normal quicksort.
(* * Dual-Pivot Quicksort algorithm * Vladimir Yaroslavskiy * First revision: February 16, 2009 * Last updated: September 11, 2009 *) let swap (data:'a[]) i j = let tmp = data.[ i ] data.[ i ] <- data.[j] data.[j] <- tmp let rec insertSortExtendedAux (data:'a[]) left right i j = if i <= right then if j > left && data.[j] < data.[j - 1] then swap data j (j - 1) insertSortExtendedAux data left right i (j - 1) else insertSortExtendedAux data left right (i+1) (i+1) let insertSortExtended data left right = insertSortExtendedAux data left right (left+1) (left+1) let ArrayDivisor = 3 let rec dualQuickSortExtended data left right = let len = right - left if len < 27 then insertSortExtended data left right else let third = len / ArrayDivisor //medians let mutable m1 = left + third let mutable m2 = right - third if m1 <= left then m1 <- left + 1 if m2 >= right then m2 <- right - 1 if data.[m1] < data.[m2] then swap data m1 left swap data m2 right else swap data m1 right swap data m2 left //pivots let pivot1 = data.[left] let pivot2 = data.[right] //pointers let less = ref <| left + 1 let great = ref <| right - 1 let inline pivotAroundLess k = swap data k !less incr less let inline pivotAroundGreat k = swap data k !great decr great //sorting for k in !less .. !great do if data.[k] < pivot1 then pivotAroundLess k elif data.[k] > pivot2 then while k < !great && data.[!great] > pivot2 do decr great pivotAroundGreat k if data.[k] < pivot1 then pivotAroundLess k //swaps let dist = let delta = !great - !less if delta < 13 then delta + 1 else delta swap data (!less - 1) left swap data (!great + 1) right //subarrays dualQuickSortExtended data left (!less - 2) dualQuickSortExtended data (!great + 2) right if dist > len - 13 && pivot1 <> pivot2 then for k in !less .. !great do if data.[k] = pivot1 then pivotAroundLess k elif data.[k] = pivot2 then pivotAroundGreat k if data.[k] = pivot1 then pivotAroundLess k //subarray if pivot1 < pivot2 then dualQuickSortExtended data !less !great let checkRange data i j s = if i < 0 then invalidArg "i" (sprintf "%s : lower index was out of bounds" s) if j >= Array.length data then invalidArg "j" (sprintf "%s : upper index was out of bounds" s) let sort data fromPos toPos = checkRange data fromPos toPos "sort data fromPos toPos" dualQuickSortExtended data fromPos toPos let runExample ()= let data = Array.init 50 (fun i -> i % 10) printf "before : %A" data sort data 0 (data.Length - 1) printf "after : %A" data