Skip to content

Introduce a specialization trait for ReadDir for most platforms#155367

Open
asder8215 wants to merge 1 commit intorust-lang:mainfrom
asder8215:read_dir_specialization
Open

Introduce a specialization trait for ReadDir for most platforms#155367
asder8215 wants to merge 1 commit intorust-lang:mainfrom
asder8215:read_dir_specialization

Conversation

@asder8215
Copy link
Copy Markdown
Contributor

@asder8215 asder8215 commented Apr 15, 2026

For most platforms, we can achieve a zero cost way of constructing a ReadDir via std::fs::read_dir when passing in a PathBuf or something that can be converted into a PathBuf (in a zero cost fashion) through a specialization trait (as std::fs::read_dir takes in an AsRef<Path>). We can use a specialization trait via what's offered by min_specialization feature.

The only platforms, as far as I can tell, that cannot achieve a zero cost way (at least conveniently) of constructing a ReadDir with an owned path is uefi since it seems like it needs to create an absolute path from a path reference (which creates and allocates for a PathBuf anyways). On Windows, this specialization trait gets rid of let root = p.into_path_buf(), reducing one PathBuf allocation, but there's already another PathBuf allocation that occurs through pushing a "*" on the path. Of course, on unsupported and vexos, since readdir is unsupported on those platforms, I didn't introduce the trait there.

I also tried out making a mock ReadDir with the min_specialization feature on rust playground and can see that an owned path and a path reference uses different functions of the specialization trait accordingly.

r? @Mark-Simulacrum since this goes hand in hand with the remove_dir_all_recursive PR I made that he's a reviewer of.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 15, 2026
}

pub fn readdir(p: &Path) -> io::Result<ReadDir> {
let path = crate::path::absolute(p)?;
Copy link
Copy Markdown
Contributor Author

@asder8215 asder8215 Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be unnecessary since internally uefi_fs::File::from_path already uses crate::path::absolute(p) on the given path reference.

View changes since the review

Comment thread library/std/src/sys/fs/unix.rs Outdated
Comment thread library/std/src/sys/fs/mod.rs
@bjorn3
Copy link
Copy Markdown
Member

bjorn3 commented Apr 17, 2026

Is this allocation actually that expensive compared to the allocation that need to be done for every returned directory entry to warrant a ton of extra code?

@asder8215
Copy link
Copy Markdown
Contributor Author

asder8215 commented Apr 17, 2026

Is this allocation actually that expensive compared to the allocation that need to be done for every returned directory entry to warrant a ton of extra code?

You're right to point this out since each DirEntry produced by ReadDir already performs allocation to store the entry name; in most cases, I'd presume that this DirEntry allocation dominates over constructing a ReadDir on each nested directory.

However, I guess I've been thinking about why not just potentially improve the performance and usage of building ReadDir even if it's slightly (though there is code maintenance and churn here to think about of course)? If someone's building a ReadDir iterator using a PathBuf be it initially or through a nested directory, I don't know why they should pay the cost of allocating for another PathBuf if they gave one directly. I think about this blog post I read before on how it's an anti-pattern to use AsRef if you're doing something like let x = param.as_ref().to_owned();, which should use Into instead, and I agreed with its point here. I just thought it was a little disappointing that a function like this, which allocates for a given path regardless if it's owned or not, exists in the standard library (which I assume we can't turn this into Into due to breaking changes). When I read about specialization being possibly usable here from the libs-team notes on my ACP for ReadDir, I just figured it was an opportunity to make this similar to how Into would work for this function.

The effects of how big this change makes for performance is something that I should benchmark. The remove_dir_all_recursive for unix/uefi (less so on uefi since I couldn't introduce the trait there) is one of those functions that I noticed could have been improved by this change since it could've used less memory and avoid an allocation on each recursive call (and it seems to be used pretty often within the rust repo).

…on most platforms to construct a ReadDir with zero cost conversion if given a PathBuf or something that could be converted into a PathBuf
@asder8215 asder8215 force-pushed the read_dir_specialization branch from 2858476 to 13a0cee Compare April 17, 2026 13:41
@Mark-Simulacrum
Copy link
Copy Markdown
Member

I don't think this complexity is warranted, especially given it needs specialization which carries some correctness risk too. But I'll r? @the8472 if you want to take review here.

@rustbot rustbot assigned the8472 and unassigned Mark-Simulacrum Apr 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants