\$\begingroup\$

How do I go about finding out what's keeping the Rust version from being faster?

In the general case you would use a profiler like Linux's perf tool to give you a rundown of which functions are eating up all your time. But perf is broken on my computer at the moment and I don't feel like fixing it, so let's try some more Rust-specific advice. :)

The first thing to do is note that print! is a macro (note the exclamation point!), which means that it's expanding at compile-time to do... something. We can figure out what that something is by passing --pretty expanded to the compiler, yielding this:

#![feature(phase)] #![no_std] #![feature(globs)] #[phase(plugin, link)] extern crate "std" as std; #[prelude_import] use std::prelude::*; fn main() { let mut reader = io::stdin(); for line in reader.lock().lines() { match line { Ok(l) => match (&l,) { (__arg0,) => { #[inline] #[allow(dead_code)] static __STATIC_FMTSTR: &'static [&'static str] = &[""]; ::std::io::stdio::print_args(&::std::fmt::Arguments::new(__STATIC_FMTSTR, &[::std::fmt::argument(::std::fmt::Show::fmt, __arg0)])) } }, Err(_) => continue , } } }

Yikes... that's a whole lot of stuff just for printing a line via a type-safe format string. In truth we really don't care about type-safe format strings in this application, given that we want an apples-to-apples comparison to C, so we can get rid of the macro entirely... but what to replace it with? I could give you the step-by-step, but instead I'll point you to the stdio docs and let you poke around at your leisure: http://doc.rust-lang.org/std/io/stdio/

Here's the result of me perusing the docs there:

use std::io; fn main() { let mut reader = io::stdin(); let mut writer = io::stdout(); while let Ok(c) = reader.read_u8() { writer.write_u8(c); } }

This looks much more directly comparable to your C program.

(If you're wondering what while let foo does, it is simply treated as an infinite loop that breaks whenever you get an enum that isn't foo . In this case, reader.read_u8() returns an IoResult , and will give you the Ok variant when it gets a char or the Err variant when it hits EOF. See read_u8 's documentation here: http://doc.rust-lang.org/std/io/trait.Reader.html#method.read_u8)

I'm sure this program could be optimized further, perhaps by investigating the stdin_raw() and stdout_raw() functions mentioned in the stdio docs. But this should give you a good starting point, and give you the tools to dig deeper yourself.