For everyone involved in timing, I would like to warn you that the execution order is extremely important. For example, consider the following two subtle time tests:
(one)
res = Table[ a = RandomReal[{0, 100}, 10^8]; { Min[a] // AbsoluteTiming // First, Max[a] // AbsoluteTiming // First, Max[a] // AbsoluteTiming // First, Min[a] // AbsoluteTiming // First } , {100} ]

The odd man here is the last Min
(2)
res = Table[ a = RandomReal[{0, 100}, 10^8]; { Max[a] // AbsoluteTiming // First, Min[a] // AbsoluteTiming // First, Min[a] // AbsoluteTiming // First, Max[a] // AbsoluteTiming // First } , {100} ]

Here, the highest timeline is found for the first Max , the second is the highest for the second Max , and two Min approximately the same and the lowest. In fact, I would expect that Max and Min will take about the same time, but they will not. The former, apparently, takes 50% more time than the latter. It seems that the position of the pole has a 50% disadvantage.
Now a comparison with the algorithms given by Mark and Leonid:
res = Table[ a = RandomReal[{0, 100}, 10^8]; { {Max[a], Min[a]} // AbsoluteTiming // First, { Min@ #, Max@ #} &@a // AbsoluteTiming // First, getMinMax[a] // AbsoluteTiming // First, minMax[a] // AbsoluteTiming // First, {Min[a], Max[a]} // AbsoluteTiming // First } , {100} ]

Here we find about 0.3 s for {Max [a], Min [a]} (which includes a checkmark on the pole), level .1 is for the Mark method; all the rest are about the same.