On my system, reverse_complement < input25000000.txt spends 67% of its time on the read_to_end call here. According to the profile, that time is almost all spent in memmove.
let mut data = Vec::with_capacity(1024 * 1024);
stdin.lock().read_to_end(&mut data).unwrap();
Increasing the initial buffer size to fit the entire dataset cuts the read_to_end time in half, and reduces the total execution time by about 30%, but obviously it also wastes memory if the data is small. (Since this program reads from stdin, it doesn't known the total size before it starts reading.)