slyons / rust-module-of-the-week

A weekly dive into commonly used modules in the Rust ecosystem, with story flavor!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Alternative implementation of visit_dirs

Plecra opened this issue · comments

fn visit_dirs(dir: &Path) -> io::Result<Vec<PathBuf>> {
    let mut stack = vec![fs::read_dir(dir)?];
    let mut files = vec![];
    while let Some(dir) = stack.last_mut() {
        match dir.next().transpose()? { // r: dir.find_map(|r| r.ok())
            None => {
                stack.pop();
            }
            Some(dir) if dir.file_type().map_or(false, |t| t.is_dir()) => {
                stack.push(fs::read_dir(dir.path())?); // stack.extend(fs::read_dir(dir.path()))
            }
            Some(file) => files.push(file.path()),
        }
    }
    Ok(files)
}

Recursion in Rust isn't specially optimised, so iterative solutions are often faster (in this case 3x). I think it would be good to make a note of this.

Also, it's often better to just ignore errors returned from the ReadDir since they can have different permission flags etc. In these cases discarding the rest of the results can be overly pessimistic.

Recursion in Rust isn't specially optimised, so iterative solutions are often faster (in this case 3x). I think it would be good to make a note of this.

Oh no my functional programming is showing :) This is a solid point and I appreciate it. I think updating the document with a block showing the iterative version in another section below the recursive one should cover it. Offer it as the better alternative.

Also, it's often better to just ignore errors returned from the ReadDir since they can have different permission flags etc. In these cases discarding the rest of the results can be overly pessimistic.

I was going to get into permissions in part 3, since it seems to be an issue that occurs less often.