use generics instead of dynamic dispatch internally in tar::Builder
#395
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR Using generics instead of dynamic dispatch allows for specialization and a performance win on modern Linux systems.
(look here for full benchmark details)
This PR is specifically targeted to allow triggering the specialization of the
Write
implementations when usingtar::Builder
. In particular, the stdlib has a specialization on Linux forstd::io::copy
that allows it to use thecopy_file_range
syscall. Unfortunately the code as-is is not capable of performing such specialization (or potentially others) since it relies on dynamic dispatch internally. This PR changes the underlying implementation to uses generics instead of dynamic dispatch. This understandably comes at the potential cost of increased code size but I'd argue this choice is already exposed to users that should be willing to pay the code size cost when usingtar::Builder<T>
directly instead oftar::Builder<dyn Write>
. Users looking for reduced code footprint can explicitly opt in through usingtar::Builder<dyn Write>
instead.PS: I had to change one of the tests because it looks like this specialization behaves differently than the usual before. Previously since the
pax_simple_write
test was using aBufWriter
it would try toappend_file
the archive inside the archive itself. That would work because the writes to the file would be buffered and thus reading the archive at that point would read nothing. But withcopy_file_range
that is no longer true. Anyway, I am pretty sure this was a bug in the test code, but if not, the correct fix would be to do some sort of inode tracking like tar does.