Reading numbers from a file


#1

Hi All!

I just started to explore Rust, and have created a very tiny program, which reads in a lot of (100k) numbers from a file (one number per line).

It looks like this:

fn main() {
    let path = Path::new("numbers.txt");
    let mut fileReader = BufferedReader::new(File::open(&path));
    let mut vector: Vec<isize> = vec![];

    for line in fileReader.lines() {
        match line {
            Err(why)   => panic!("{:?}", why),
            Ok(string) => match string.trim().parse::<isize>() {
                None        => panic!("Not a number!"),
                Some(number)=> vector.push(number)
            }
        }
    }
}

So basically, I read the file line by line then convert every line to a number.

I’ve created the same program in Go and Python and they seem to be somewhat faster (go nearly about 20%, python about 50%).
Of course, all of them are quite fast so it’s not a big deal, I just wonder whether I took the right approach (i.e. I’m doing things in the “rusty” way :-)).
I also understand that I use a few unstable features and as I’ve read the IO is still subject to change.

The version I use is: rustc 1.0.0-nightly (c5961ad06 2015-01-28 21:49:38 +0000)

So, the question is: am I on the right track, or there are some possibilities to tweak this method a bit more?

Thanks in advance!

Cheers!


#2

A few things:

they seem to be somewhat faster

How did you compile this code? If you’re using Cargo (and you should be), make sure to do cargo build --release and/or cargo run --release. Without the release flag, you get no optimizations, and that will be significantly slower.

i.e. I’m doing things in the “rusty” way :slight_smile:

This code is pretty good overall, but I would not use an isize here, I’d use an i32, unless I knew the numbers in the text file were bigger than it.


#3

Thanks for your reply!

So far, I have only used rustc, but running it with cargo using the release flag made it 3x faster, thanks a lot! :+1:

Cheers!


#4

Cool. :smile: If you’re using bare rustc, add a -O parameter, which turns
on optimizations.


#5

I prefer:

// This will automatically call panic with `why` if it errors
let string = line.unwrap();

// This is just nesting unnecessarily
match line {
    Err(why)   => panic!("{:?}", why),
    Ok(string) => {},
}

For custom error messages, use expect("my message") instead of unwrap().

You can do the same thing with Option. FYI, the docs actually say unwrap use is discouraged (so this may be reported as bad advice…). I find this nesting really annoying though.