Skip to content

Commit

Permalink
Speed up construction of MANIFEST.MF lines in java_stub_template
Browse files Browse the repository at this point in the history
This PR significantly improves the performance of constructing the classpath JAR `MANIFEST.MF` file in `java_stub_template`.

If the `CLASSPATH` is huge then significant time is spent wrapping the lines of the manifest to 72 characters. For example, if the classpath contains 400k characters then it takes nearly two minutes to generate the `MANIFEST.MF` file!

To speed this up, I changed the code to use the `fold` utility (instead of a `for` loop which indexes into a giant string). This is _much_ faster, processing a 400k character classpath in ~150ms (my microbenchmark code and results are at https://gist.github.com/joshrosen-stripe/96a467cd7847cef241772064ec902147)

`fold` is part of the POSIX spec so I believe that this solution will be portable.

Closes bazelbuild#8196.

PiperOrigin-RevId: 247575329
  • Loading branch information
joshrosen-stripe authored and copybara-github committed May 10, 2019
1 parent 77b5658 commit efdd3b2
Showing 1 changed file with 4 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,14 @@ function create_and_run_classpath_jar() {
CLASSPATH_LINE="Class-Path:$MANIFEST_CLASSPATH"
# No line in the MANIFEST.MF file may be longer than 72 bytes.
# A space prefix indicates the line is still the content of the last attribute.
for ((i = 0; i < "${#CLASSPATH_LINE}"; i += 71)); do
IFS=$'\n'
WRAPPED_LINES=($(echo "$CLASSPATH_LINE" | fold -w 71))
for ((i = 0; i < "${#WRAPPED_LINES[*]}"; i += 1)); do
PREFIX=" "
if ((i == 0)); then
PREFIX=""
fi
echo "$PREFIX${CLASSPATH_LINE:$i:71}"
echo "$PREFIX${WRAPPED_LINES[$i]}"
done
echo "Created-By: Bazel"
) >$MANIFEST_FILE
Expand Down

0 comments on commit efdd3b2

Please sign in to comment.