In terms of minimizing gas costs (or any other relevant benchmark), what's the best way in Solidity to sort an array of values and find the highest scores? If it matters, the numbers are all within a fairly tight range
2 Answers
I don't know if there's a best way or not, but I usually take track of the highest numbers while you add a new element on the array
function refreshTopXOrdered(uint value) private {
uint i = 0;
/** get the index of the current max element **/
for(i; i < topElementsOrdered.length; i++) {
if(topElementsOrdered[i] < value) {
break;
}
}
/** shift the array of one position (getting rid of the last element) **/
for(uint j = topElementsOrdered.length - 1; j > i; j--) {
topElementsOrdered[j] = topElementsOrdered[j - 1];
}
/** update the new max element **/
topElementsOrdered[i] = value;
}
where topElementsOrdered is just an array with a predefined size:
uint[3] public topElementsOrdered; //can be any size
this will take track of the changes while you add your elements and keep the top elements ordered (descending order).
Supposing to call it in this way
uint[] elements;
function add(uint value) public {
elements.push(value);
refreshTopXOrdered(value);
}

- 312
- 2
- 16
mirg's approach is the best way to go if you're looking to retain the top few scores. Obviously, if you need to sort all elements, then this approach won't be the most efficient way especially as the array gets longer.
In general, you should avoid sorting on the blockchain. It will be very costly and you can run into out of gas exceptions as the size of the array gets larger. If you MUST sort on the chain, you'd probably want to use heapsort.

- 10,175
- 10
- 35
- 48