Skip to content

Commit 3fc2d87

Browse files
joshrosen-stripeirengrig
authored andcommitted
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 bazelbuild#8196. PiperOrigin-RevId: 247575329
1 parent 7698655 commit 3fc2d87

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,14 @@ function create_and_run_classpath_jar() {
314314
CLASSPATH_LINE="Class-Path:$MANIFEST_CLASSPATH"
315315
# No line in the MANIFEST.MF file may be longer than 72 bytes.
316316
# A space prefix indicates the line is still the content of the last attribute.
317-
for ((i = 0; i < "${#CLASSPATH_LINE}"; i += 71)); do
317+
IFS=$'\n'
318+
WRAPPED_LINES=($(echo "$CLASSPATH_LINE" | fold -w 71))
319+
for ((i = 0; i < "${#WRAPPED_LINES[*]}"; i += 1)); do
318320
PREFIX=" "
319321
if ((i == 0)); then
320322
PREFIX=""
321323
fi
322-
echo "$PREFIX${CLASSPATH_LINE:$i:71}"
324+
echo "$PREFIX${WRAPPED_LINES[$i]}"
323325
done
324326
echo "Created-By: Bazel"
325327
) >$MANIFEST_FILE

0 commit comments

Comments
 (0)