How can I input and output contents fastest in output stream in a OJ system?

Firstly, I want to input and output a serious of numbers as fast as it can. Secondly, I found out that I have to change a number(e.g i32) to string to output to standard output stream.
so I have three questions:
Q1: Is there any method to input multiple lines of strings as fast as I can?
Q2: Is there any method to output multiple lines of strings as fast as I can?H
Q3: ow do I output a number in standard output stream without cast it to string?

First, I feel obliged to mention that for all real world use cases, using the standard library to read from stdin (e.g. via the read() method on a std::io::Stdin instance) or write to stdout (e.g. via println!() or writing to an instance of std::io::Stdout) is more than sufficient.

That said, there are some ways you can improve the input and output of your application by things like buffering and memory-mapped files.

If your data is coming from a file then you can always ask the OS to map the file directly into your program's address space (i.e. the OS will give you a pointer and dereferencing it will magically read data from disk). Crates like memmap provide a nice wrapper around these OS-specific APIs.

I'm taking "fast" to mean throughput (i.e. the most bytes per second).

The typical way you improve your program's output throughput is by using a buffer to emit a small number of very writes instead of lots of little ones. This works because each write call to stdout involves a fixed amount of overhead regardless of the amount of data being written.

See the std::io::BufWriter type for more.

Things which go through Rust's normal formatting machinery (i.e. write!() and print!()) don't do any "casting" of numbers to strings before they are written to their destination.

Instead, you can think of the Display impl's fmt() method writing the number digit-by-digit directly to the destination (e.g. by repeatedly dividing by 10 until the number is zero, writing the remainder to the destination as it goes).

You may be interested in the atoi, itoa, and dtoa crates.

For inputting floats, there was a recent discussion on IRLO; maybe there's something useful there, I didn't dig into it.

Thanks for your help, but I am trying using Rust on a OJ, and unfortunately it cannot use any other crates except std(looks like pretty limited for rust?), but generally Rust can run as fast as C(gcc) in some cases, so I think thats acceptable.

Thanks for your help. I am try to figure out how fast Rust can be in OJ, considering time consue and memery use, direct output stream still leading the way, but a little difficult to use, It perform pretty well now, maybe that the limit. :smiley:

I would also suggest creating benchmarks for this sort of stuff and testing throughput yourself. I suggest looking into the criterion crate.

Just asking "what is the fastest?" in general may not be useful to you because performance varies depending on what is being printed. For example, std::fmt (the machinery underneath the write!() and println!() macros) might be great at printing long &str strings but encounters a performance cliff when printing a slice of small integers, whereas C++'s std::iostream may be excellent at printing lots of small numbers and completely fall over when it comes to floats, or C's printf() may struggle when you provide long format strings because it needs to be parsed at runtime.

Those are just examples and I doubt std::iostream would actually have issues with floats, but the point I am trying to make is that different formatting libraries may have different performance characteristics depending on the data being printed. The only way to be sure is by writing benchmarks using your application.

This isn't directly related to the question, but what does OJ stand for?

Thanks for your suggestion, you are right, I also found that macros like format!() or println!() can reduce time consume in output a very long string.
And the "OJ" is a programming online judge platform for programming ability test PAT test website, just like ICPC or something like Leetcode , and the campaign rules are: I can only use std liborary, and I can only read input from standard keyboard input instead a .txt file, and what's difficult is that the input time is included in program time consume. So I have to reduce the time comsume on input contents.
I am a freshman on Rust programming. I know algorithm is much more important than input or output, but I still feel that it looks like Rust is lacking in a convenient and fast input method.

I don't quite understand what is making you say that Rust doesn't have a way to read conveniently and quickly. This sounds more like a lack of familiarity than a lack of functionality.

For example, I can implement a basic REPL in a dozen lines:

use std::io::{self, Error, Write};

fn main() -> Result<(), Error> {
    let stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut buffer = String::new();

    loop {
        // Make sure we clear out any previous messages
        buffer.clear();

        // Print our prompt and make sure it gets written to the console
        // Note: we aren't using print!() here because that only flushes 
        // to the screen when it sees a newline.
        write!(stdout, "> ")?;
        stdout.flush()?;

        // Read our input
        stdin.read_line(&mut buffer)?;

        // Handle the message
        match buffer.trim() {
            "ping" => println!("pong"),
            "quit" => break,
            other => eprintln!("[Error] Unable to handle command: {}", other),
        }
    }

    Ok(())
}

(playground)

It sounds like you are looking for some magic function which will read data from stdin 10x faster than the standard library, but I'd like to ask you this.. What makes you think the standard library isn't trying to use the fastest method for reading input already?

Ok, I think I should revise my expression. I am not complaining of Rust's speed, actually, I am pretty satisfied with it, as in my case, it runs as fast as C(gcc), that is enough for me.
What I want to know is that is there any method to write a lot of lines of digit(i32 e.g.) directly to a output stream or buffered stream without using transform like .to_string() (that's ptetty frequently in my exam-oriented education). And is there any method to get keyboard input like cin>> or scanf()in C++ or C, which is quite intuitional, or how to write it in Rust's style.
My example code is bellow, err handling is omitted:

use std::io;
use std::io::Write;

fn main() ->io::Result<()>{
    //Firstly, I get a digit from keyboard input by input stream
    //Then, Parse it to a "i32" digit
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let digit=input.trim().parse::<i32>().unwrap();

    //Then I input the "digit" to function "gettimes" to get a number
    //Finally, I parse the "i32" number returned 
    //from function "gettimes" to a string, 
    //add a "\n" to it and write it to standard output stream
    //What I want is write this digit:i32 directly to my output stream
    io::stdout().write((gettimes(digit).to_string()+"\n").as_bytes())?; 
    
    Ok(())
}

//Function "getatime": if digit "n" is a odd number, then n=3*n+1,
//if n is a even number, then n=n/2
//until n==1,return how many times the n was divided by 2;
fn gettimes(mut n:i32)->i32{
    let mut times=0;
    while n!=1 {
        if n%2==0 {
            n=n/2;
            times+=1;
        }else{
            n=n*3+1;
        }
    }
    times
}

You can use the write! or writeln! macros like in @Michael-F-Bryan's example.

writeln!(stdout, "The digit is {}", gettimes(digit))?;

Or just use println! of course.

OK, I got that.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.