-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mutating stat!
function for non-allocating filesystem stat
#46410
Conversation
Out of curiosity, what is the performance difference if you run it on something more realistic? Calling |
That's actually the use-case I was noticing the allocations for. Here's a real-world scenario where I'm looping over and checking 46 files. With
With
Pretty much in the same ballpark in terms of benefits. I think it's worth noting also that for real-time applications (which isn't a huge concern for my present problem), the worst-case scenario is improved by an order of magnitude (since it avoids the GC trigger) |
They aren't going to be calling |
In that case, disregard that remark 🤷♀️ FWIW, I was tracking down performance issues with some in-house code, and calls to |
Bumpity-bump 😊 |
|
||
Return a buffer of bytes of the right size for [`stat!`](@ref). | ||
""" | ||
get_stat_buf() = zeros(UInt8, Int(ccall(:jl_sizeof_stat, Int32, ()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this size not consistent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was adopted from the allocating implementation. I don't know if it can be safely replaced by a hard-coded constant, if that is what you mean?
Looks good to me |
This had no tests at all. Also, not added to the docs, if it was meant to be public API. |
well it's not exported and has no docs, so it's not public API? but yeah, I was probably hasty on merge. |
That's why I said "if it was meant to be public API". |
I believe |
The point of the PR was to add |
I think this is worth exporting. |
I feel like we should revert that. I don't really see the point in having a non-allocating |
I'm not going to die on a hill defending this, but I would like to understand your argument. The point is to be able to avoid allocations in a function that can easily be made to re-use a block of memory, instead of forcing the user to allocate a new one at every invocation, at no extra maintenance cost. It provides a way for the user to opt in to a marginal performance improvement, if they so wish. |
@vtjnash, can you elaborate on why you don't feel like this is worth having? The allocation is too small to matter? The compiler is likely to be able to eliminate it? What's the thinking? |
It is too insignificant, and easy for the compiler to eliminate if we cared |
The current implementation of
Base.Filesystem.stat
always allocates a temporary buffer of 224 bytes to hold the output ofjl_stat
for each call. When callingstat
on a large number of files, this has a small performance overhead and may cause GC to trigger. This PR adds a mutatingBase.Filesystem.stat!
function that allows you to pass in a pre-allocated buffer to be re-used in consecutive calls tostat!
, as well as a function,Base.Filesystem.get_stat_buf
for getting a re-usable buffer.On my machine, this results in the following improvements:
With
stat
:With
Base.Filesystem.stat!
: