Fastest reading and writing to/from stdin/stdout possible

Hello, I got a chance to be a part of school's competitive programming. I've got a small problem. We have to make a fastest key-value storage possible. That's not an issue. I've got a 170 MB input with instructions like 'Store key value' or 'Output key' or 'Remove key'. How do I read it as fast as possible? I've tried to read it with

fn main() {
    let instant = Instant::now();
    let mut buffer: Vec<u8> = Vec::with_capacity(200_000_000);
    let input = io::stdin();
    let mut input_lock = input.lock();

    while input_lock.read_until(b'\n', &mut buffer).ok() > Some(0) {
    }

    println!("Time: {}ms", instant.elapsed().as_millis());
}

but it takes around 300ms which is quite a long time. Fastest time is currently about 800ms but it's reading, executing these operations and outputting the "Output" operation.

I've heard that println is also quite slow, is there any alternative that's also blazingly fast?
PS: My friend was able to read it in 70ms in C++ so it should be also possible in Rust :smiley:
Thank you for all your help!

1 Like

With what capacity do you create the empty buffer? Are you creating a new one for each read or do you keep it around from earlier iterations? Do you make sure that it doesn't shrink between iterations if reused?

It's created from the start with 200_000_000 capacity. That's a last capacity at the end of the program. I've added a whole code for my program.

As you have an empty loop, what is it that takes "too long"? Reading a single line or reading the full input? Are you sure that reading the input is actually the bottleneck?

What is passing this data to your stdin? If it's read from disk with something like cat, can't the disk IO be the slowest part?

I've actually found a way to make it to 80ms :slight_smile:
I had to read it first as a whole to Vec<u8> and then work with it

    input_lock.read_to_end(&mut buffer);
    buffer.iter().for_each(|&character| {
        
    });
2 Likes