Improve implementation of remove_dir_all_recursive for unix#154829
Improve implementation of remove_dir_all_recursive for unix#154829asder8215 wants to merge 1 commit intorust-lang:mainfrom
Conversation
|
r? @jhpratt rustbot has assigned @jhpratt. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| // in the ReadDir struct through a method that return &Path, we can reduce memory usage | ||
| // allocated to this VecDeque. | ||
|
|
||
| let mut directories = VecDeque::new(); |
There was a problem hiding this comment.
Also, noting that this could use the std library LinkedList implementation if the resizing cost from VecDeque is undesirable.
e933993 to
a2793e4
Compare
|
@rustbot reroll |
|
Can you share more about the motivation for doing this? You mention a performance improvement, but don't mention any specific benchmarks (I personally would expect the syscall cost to dominate any improvement here, but I could be wrong). |
As it stands now, there are some things in the PR that I need to add that I believe would result in an improvement over the current recursive version of this function. I made an However, my motivation for this comes from seeing how From the curr impl of fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
for child in fs::read_dir(path)? { // <-- allocating for a PathBuf here
let result: io::Result<()> = try {
let child = child?;
if child.file_type()?.is_dir() {
// child.path() returns a PathBuf. instead of passing a ref
// for `ReadDir` to make a copy of it, just let it be owned
// by `ReadDir` directly
remove_dir_all_recursive(&child.path())?;
} else {
fs::remove_file(&child.path())?;
}
};
if let Err(err) = &result
&& err.kind() != io::ErrorKind::NotFound
{
return result;
}
}
ignore_notfound(fs::remove_dir(path))
}The other thing to point out is that because I did read through the libs team notes on this proposal, and they made a good point that specialization could work here (which makes the |
|
I was thinking about this yesterday and I think we could preserve the recursive implementation, but we could change the signature of the function to |
This PR essentially changes the underlying
remove_dir_allimplementation used by unix and I believe uefi platforms from a recursive-based approach to an iterative version. The order it removes directories and files from the recursive version should be preserved in this iterative version. I'm curious if this iterative approach could show any performance improvement over the current recursive based approach thatremove_dir_allhas on unix/uefi platforms.I also made a comment on how this iterative-based approach is redundantly holding a
PathBufin the tuple (which could incur a big allocation cost if we are removing deeply nested directories). This could be optimized if we are able to retrieve a reference to the path thatReadDirstruct is holding, as it contains this information in itsInnerReadDir'srootfield; I believe this would also make the iterative approach allocate less memory than the recursive approach as we would only need the main directory/nested directories&Pathvalues when we are removing it.I can make an ACP for
ReadDirstruct root path to be accessible via a method if that would be appropriate.