Отвечаю на свой же вопрос
class SortableSplFixedArray extends SplFixedArray {
/**
* Take an array and build an instance of the current class around it. No need
* to overwrite this for children.
* @static
* @param array $array
* @return array
*/
public static function fromArray(array $array) {
$class = __CLASS__;
$instance = new $class(count($array));
$i = 0;
foreach($array as $value) {
$instance[$i++] = $value;
}
return $instance;
}
/**
* Publicly accessible method for sorting the FixedArray
* @param int|callable $dir - can be either a sort flag (SORT_ASC or SORT_DESC)
* or a user-defined comparison function
*/
function sort($dir = SORT_ASC) {
if($dir == SORT_ASC) {
$comp_function = function($a, $b) {
return $a<$b;
};
} else if($dir == SORT_DESC) {
$comp_function = function($a, $b) {
return $a>$b;
};
} elseif(is_callable($dir)) {
$comp_function = $dir;
} else {
trigger_error('Bad argument provided for sort flag. Valid parameters are '
. 'SORT_ASC, SORT_DESC, or a user-defined sorting function');
//proceed as though SORT_ASC
$comp_function = function($a, $b) {
return $a<$b;
};
}
$this->_quicksort($comp_function, 0, $this->getSize()-1);
}
/**
* Finds a pivot point using a 'midpoint of three' procedure
* @param int $left - left index
* @param int $right - right index
* @return array - array contains the pivot's index and its value
*/
protected function _pivot_selection_function($left, $right) {
$midpoint = (int)(((($right-$left)%2)==1) ? (($right-1-$left)/2 + $left) :
(($right-$left)/2 + $left));
if($this->offsetGet($right)<$this->offsetGet($left)) {
if($this->offsetGet($midpoint) > $this->offsetGet($right)) {
return array($right, $this->offsetGet($right));
} else {
return ($this->offsetGet($midpoint) > $this->offsetGet($left)) ?
array($midpoint, $this->offsetGet($midpoint)) :
array($left, $this->offsetGet($left));
}
} else {
if($this->offsetGet($midpoint) > $this->offsetGet($left)) {
return array($left, $this->offsetGet($left));
} else {
return ($this->offsetGet($midpoint) > $this->offsetGet($right)) ?
array($midpoint, $this->offsetGet($midpoint)) :
array($right, $this->offsetGet($right));
}
}
}
/**
* Implement a recursive quicksort algorithm ordering based on the passed-in
* comparison function
* @param callable $comp_function
* @param int $left_offset
* @param int $right_offset
*/
protected function _quicksort($comp_function, $left_offset, $right_offset) {
if($right_offset - $left_offset < 1) return;
list($key, $value) = $this->_pivot_selection_function($left_offset,
$right_offset);
if($key != $left_offset) {
$this->_swap($left_offset, $key);
}
$j = $left_offset+1;
$has_larger = false;
for($i=$j; $i <= $right_offset; $i++) {
$val = $this->offsetGet($i);
$comp = $comp_function($val,$value);
if($has_larger && $comp) {
$this->_swap($j, $i);
$j++;
} elseif($comp) {
$j++; //just advance pointer, no swap
} elseif(!$has_larger) {
$has_larger = true;
}
}
$this->_swap($left_offset, $j-1);
$this->_quicksort($comp_function, $left_offset, $j-2);
$this->_quicksort($comp_function, $j, $right_offset);
}
protected function _swap($i, $j) {
$temp = $this->offsetGet($j);
$this->offsetSet($j, $this->offsetGet($i));
$this->offsetSet($i, $temp);
}
}
$M = new SortableSplFixedArray(100000);
for($i=0;$i<$count;$i++){
$M[$i]=mt_rand(1, 1000000);
}
$M ->sort(SORT_ASC);