This is called an adaptive sort algorithm. The timsort sorting algorithm has this property. It is the algorithm used by the Rust standard library for slice::sort. From the documentation:
The current algorithm is an adaptive, iterative merge sort inspired by timsort. It is designed to be very fast in cases where the slice is nearly sorted, or consists of two or more sorted sequences concatenated one after another.
use std::time::Instant;
fn main() {
for n in (1 << 16..1 << 20).step_by(1 << 16) {
let mut v = (0..n).collect::<Vec<_>>();
let tic = Instant::now();
v.sort();
println!(
"{n}: {:?}/item",
(Instant::now() - tic).as_secs_f64() / n as f64
);
}
}
So slice::sort is quite reliable when it comes to sorting already-sorted arrays. Note that sort_unstable() is even faster, so you should use that when you get the chance.