From efdd3b270faaaf9bca6439da4fc177e97296c1bd Mon Sep 17 00:00:00 2001 From: Josh Rosen Date: Fri, 10 May 2019 02:02:37 -0700 Subject: [PATCH] Speed up construction of MANIFEST.MF lines in java_stub_template 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 #8196. PiperOrigin-RevId: 247575329 --- .../build/lib/bazel/rules/java/java_stub_template.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt index 27e576344c4ea0..53499a34ea83af 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt @@ -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