3 ms·
I think you've seen this comment about integer overflow optimizations? https://www.reddit.com/r/rust/comments/ab7hsi/comparing_pythagorean_triples_in_c_d_and_ru
by ekidd 8y ago
I think you've seen this comment about integer overflow optimizations? https://www.reddit.com/r/rust/comments/ab7hsi/comparing_pythagorean_triples_in_c_d_and_rust/ecy5pv7/?st=jqchvb9f&sh=0b2616c6 https://www.reddit.com/r/rust/comments/ab7hsi/comparing_pyth...
But I also note that the original version of your benchmark was calling `println!`, which means that you were essentially benchmarking high-level, thread-safe I/O. EDIT: Not in this case, see the thread below.
Some Rust benchmarking tips:
1. Always run `cargo build --release`. Debug builds are slow.
2. Be sure to use `stdin.lock()` or `stdout.lock()` when reading or writing standard I/O. If you don't, Rust has to lock standard I/O for you on each call. This means using `writeln!` instead of `println!`.
- burntsushi 8y ago> But I also note that the original version of your benchmark was calling `println!`, which means that you were essentially benchmarking high-level, thread-safe I/O. I don't think so. The program is only doing a thousand prints, which is far less than the total number of loop iterations. Try changing to locked stdout and writeln!---I doubt you'll notice a difference.
- lambda 8y agoYeah, I tried the locking version and didn't see a noticeable improvement.
- ekidd 8y agoThank you for checking this, and determining it didn't actually apply in this case. We do a lot of I/O intensive Rust at work, and I have a list of things to double-check when benchmarking. The most common slowdowns: debug builds, unlocked stdio, line iterators, and anything else which allocates in an inner loop. If I can hit 250 MB/s throughput per core on my laptop, with some light data processing, I'm usually quite happy.
- fanf2 8y agoI think the problem is flushing, not locking. Rust println!() flushes after each call, whereas more C-like io libraries flush once on program exit. Big difference in the number of system calls.
- steveklabnik 8y agoEDIT: THIS IS ALL WRONG AND BACKWARDS, SEE BELOW -------------------------- > Rust println!() flushes after each call, To be clear, println! does not flush after each call. Many terminals are line-buffered, and so when println! emits a \n, the terminal will flush. So, println! will probably cause a flush, but does not flush itself. println! is the exact same as `print!`, except for the additional printing of \n https://doc.rust-lang.org/stable/src/std/macros.rs.html#157-162 https://doc.rust-lang.org/stable/src/std/macros.rs.html#157-...
- burntsushi 8y agoAre you sure about this? AFAIK, println! uses io::stdout(), which is defined like so: pub struct Stdout { inner: Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>, } In particular, it's specifically using LineWriter internally, which does flush whenever it sees a `\n`. println! does not itself explicitly flush, but its current implementation does guarantee that it will. However, I don't think this is an API guarantee. In the definition of Stdout, there is this FIXME: // FIXME: this should be LineWriter or BufWriter depending on the state of // stdout (tty or not). Note that if this is not line buffered it // should also flush-on-panic or some form of flush-on-abort. Which basically means that someone thought its buffering strategy should be determine by whether or not stdout is connected to a tty. This is what ripgrep does for example, but I had to build out my own infrastructure to do it: https://docs.rs/grep-cli/0.1.1/grep_cli/#coloring-and-buffering https://docs.rs/grep-cli/0.1.1/grep_cli/#coloring-and-buffer... --- Arguably, io::stdout() should do the same. I don't think buffer configuration at the level of the terminal plays a role here. This is somewhat confused by programs like stdbuf[1] which purport to enable users to change the buffering strategy used by a program in their shell. But in reality, it appears tightly coupled with C's FILE data type and perhaps even tightly coupled with glibc itself? I'm not sure. [1] - https://www.gnu.org/software/coreutils/manual/html_node/stdbuf-invocation.html#stdbuf-invocation https://www.gnu.org/software/coreutils/manual/html_node/stdb...