I continued to tear myself away from this, but could not get it faster than the sorting method. This leads to the fact that each key pair is unique, which I did not mention above.
% This gives us unique rows of integers between one and 10000, sorted first % by column 1 then 2. x = unique(uint32(ceil(10000*rand(1e6,2))),'rows'); tic; idx = zeros(size(x,1),1); % Work out where each group of the second keys will start in the sorted output. StartingPoints = cumsum([1;accumarray(x(:,2),1)]); % Work out where each group of the first keys is in the input. Ends = find([~all(diff(x(:,1),1,1)==0,2);true(1,1)]); Starts = [1;Ends(1:(end-1))+1]; % Build the index. for i = 1:size(Starts) temp = x(Starts(i):Ends(i),2); idx(StartingPoints(temp)) = Starts(i):Ends(i); StartingPoints(temp) = StartingPoints(temp) + 1; end % Apply the index. y = x(idx,:); toc tic; z = sortrows(x,2); toc isequal(y,z)
It gives 0.21 seconds for my algorithm and 0.18 for the second (stable for different random seeds).
If anyone sees further speed (except mex), feel free to add.
source share