-
Notifications
You must be signed in to change notification settings - Fork 13.7k
rust-installer/install-template.sh: improve efficiency, step 1. #145809
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
base: master
Are you sure you want to change the base?
Conversation
This round replaces repetitive pattern matching in the inner loop of this script using grep (which causes a fork() for each test) with built-in pattern matching in the bourne shell using the case / esac construct. This in reference to rust-lang#80684 and is a separated-out request from rust-lang/rust-installer#111 which apparently never got any review. The forthcoming planned "step 2" change builds on top of this change, and replaces the inner-loops needless uses of sed (which again causes a fork() for each instance) with the suffix removal constructs from the bourne shell. Since this change touches lots of the same lines this change does, that pull request cannot be submitted before this one is accepted. Hopefully this first step is less controversial than the latter change.
rustbot has assigned @Mark-Simulacrum. Use |
Hi, thanks for the PR! Did you try to run any benchmarks (i.e. install a tarball component before/after) the change? |
bin/*) | ||
run cp "$_src_dir/$_component/$_file" "$_file_install_path" | ||
run chmod 755 "$_file_install_path" | ||
;; |
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.
This seems like a useful change of behavior, but you did not mention it in your PR summary.
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.
I am a little uncertain what "this" refers to. There was no intention to change the behavior of the script. Note that the test in the previous "if" had an "or", so both tests needs to be covered going forward, and that is what I think the new code does. The case
construct can only cover the test for the path name, and cannot test for the executeable-ness of the file.
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.
Ah right, I misread. Still I don't understand why these couldn't be combined like in the original code, perhaps by first testing for "bin"ness and saving the result in a variable, then doing the if-or?
Admittedly no. However, this set of modifications came about because this script was absurdly slow when doing the builds / install during my testing of the various rust releases up through the ages, on & for the various different NetBSD targets. To run a benchmark I would have to figure out how to rig up a test scaffolding for this script, since just doing this as part of a full build will take way too long time. To me it is sort of obvious that doing a massive number of avoidable The question can of course come from a couple of different perspectives:
I am hoping the question doesn't come from the third perspective. The second perspective also should not be a valid objection; as the referenced issue describes, it is well known that this script in its current form is just slow. |
@bors try Let's produce some artifacts -- I think the install scripts aren't exercised anywhere(?) in our normal release process, so it'll need some manual testing. |
rust-installer/install-template.sh: improve efficiency, step 1.
This comment has been minimized.
This comment has been minimized.
It's a larger change, but I'm also wondering why this was written as a shell script. AFAICT, this is always bundled into a tarball we produce that contains some kind of binary artifacts. Maybe this could be a Rust program? That would (a) improve our ability to review changes and (b) likely help with performance, at least insofar as we can avoid any sub-shells that aren't needed. |
OK, I've done some testing. First off, I install rust 1.88.0 into an empty prefix via
to collect system call trace to see how many
With the original install.sh script, we get 3910 Secondly, doing the install into an already-populated prefix gets us with the original installer the following outputs from "time" in csh:
With the suggested "case / esac for pattern matching" version suggested here, I got
So ... a nearly 30% reduction in wallclock time on this particular host (which is pretty beefy, I predict that the effect will be even more pronounced on slower hosts), and a reduction in the number of And ... the reason this is particularly noticeable with the "doc" component is most probably that it has a rather larger set of files. The components installed here have relatively few:
I don't have a build with the doc component at hand at the moment. |
Yes, that would be a larger change. Why it is the way it is (a shell script), I cannot comment on at the moment. And turning this into a rust program would exceed my current rust abilities, so it would not come from this corner. However, let me suggest that we first measure the performance improvements we can get with "known fixes" to the existing script to get this from "unbearably slow" to "manageable also on slow hosts" before embarking on that larger rewrite. Expediency has to count for something... And... It also looks like this avenue has been attempted before, #80684 contains pointers to both similar suggestions (which were not taken), and some which were (the --bulk-dirs for docs). At the end of this it might be worth reviewing those other old suggestions to see which ones are still applicable. |
And ... to preview the suggested next pull request, replacing cut and sed in the inner loop of the script with parameter expansion which does "remove largest suffix pattern" and "remove shortest prefix pattern" modifications reduces the number of
So, average wall-clock time of 4.62, which is around 35% of the original timing (reduced by 65%), and the number of |
This round replaces repetitive pattern matching in the inner loop of this script using grep (which causes a
fork()
for each test) with built-in pattern matching in the Bourne shell using thecase
/esac
construct.This in reference to
#80684
and is a separated-out request from
rust-lang/rust-installer#111
which apparently never got any review.
The forthcoming planned "step 2" change builds on top of this change, and replaces the inner-loops needless uses of
sed
(which again causes afork()
for each instance) with the suffix removal constructs from the Bourne shell. Since this change touches lots of the same lines this change does, that pull request cannot be submitted before this one is accepted.Hopefully this first step is less controversial than the latter change.