Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to micro-optimize "x = max(a,b); y = min(a,b);"?

I had an algorithm that started out like

int sumLargest2 ( int * arr, size_t n )
{
    int largest(max(arr[0], arr[1])), secondLargest(min(arr[0],arr[1])); 
    // ... 

and I realized that the first is probably not optimal because calling max and then min is repetitious when you consider that the information required to know the minimum is already there once you've found the maximum. So I figured out that I could do

   int largest = max(arr[0], arr[1]);
   int secondLargest = arr[0] == largest ? arr[1] : arr[0];

to shave off the useless invocation of min, but I'm not sure that actually saves any number of operations. Are there any fancy bit-shifting algorithms that can do the equivalent of

int largest(max(arr[0], arr[1])), secondLargest(min(arr[0],arr[1]));

?????

like image 592
user4905335 Avatar asked Nov 27 '22 04:11

user4905335


2 Answers

In C++, you can use std::minmax to produce a std::pair of the minimum and the maximum. This is particularly easy in combination with std::tie:

#include <algorithm>
#include <utility>

int largest, secondLargest;
std::tie(secondLargest, largest) = std::minmax(arr[0], arr[1]);

GCC, at least, is capable of optimizing the call to minmax into a single comparison, identical to the result of the C code below.

In C, you could write the test out yourself:

int largest, secondLargest;
if (arr[0] < arr[1]) {
  largest = arr[1];
  secondLargest = arr[0];
} else {
  largest = arr[0];
  secondLargest = arr[1];
}
like image 163
rici Avatar answered Dec 04 '22 21:12

rici


How about:

int largestIndex = arr[1] > arr[0];
int largest = arr[largestIndex];
int secondLargest = arr[1 - largestIndex];

The first line relies on an implicit cast of a boolean result to 1 in the case of true and 0 in the case of false.

like image 42
samgak Avatar answered Dec 04 '22 21:12

samgak