Remove pipes usage when reading the manifest file in collect_cc_coverage.sh
Replace reading the manifest using pipes with `read -r`. Using pipes is not an efficient way to read big files.
I created a small repo that only reads:
* a 200.000-lines file:
with pipes: 0m7.965s
with read: 0m2.835s
* a 2.000.000-lines file:
with pipes: 1m21.065s
with read: 0m29.215s
Closes #8331.
PiperOrigin-RevId: 248528367
diff --git a/tools/test/collect_cc_coverage.sh b/tools/test/collect_cc_coverage.sh
index 4ee1546..c55b8e9 100755
--- a/tools/test/collect_cc_coverage.sh
+++ b/tools/test/collect_cc_coverage.sh
@@ -84,56 +84,58 @@
# Copy .gcno files next to their corresponding .gcda files in $COVERAGE_DIR
# because gcov expects them to be in the same directory.
- cat "${COVERAGE_MANIFEST}" | grep ".gcno$" | while read gcno_path; do
+ while read -r line; do
+ if [[ ${line: -4} == "gcno" ]]; then
+ gcno_path=${line}
+ local gcda="${COVERAGE_DIR}/$(dirname ${gcno_path})/$(basename ${gcno_path} .gcno).gcda"
+ # If the gcda file was not found we skip generating coverage from the gcno
+ # file.
+ if [[ -f "$gcda" ]]; then
+ # gcov expects both gcno and gcda files to be in the same directory.
+ # We overcome this by copying the gcno to $COVERAGE_DIR where the gcda
+ # files are expected to be.
+ if [ ! -f "${COVERAGE_DIR}/${gcno_path}" ]; then
+ mkdir -p "${COVERAGE_DIR}/$(dirname ${gcno_path})"
+ cp "$ROOT/${gcno_path}" "${COVERAGE_DIR}/${gcno_path}"
+ fi
+ # Invoke gcov to generate a code coverage report with the flags:
+ # -i Output gcov file in an intermediate text format.
+ # The output is a single .gcov file per .gcda file.
+ # No source code is required.
+ # -o directory The directory containing the .gcno and
+ # .gcda data files.
+ # "${gcda"} The input file name. gcov is looking for data files
+ # named after the input filename without its extension.
+ # gcov produces files called <source file name>.gcov in the current
+ # directory. These contain the coverage information of the source file
+ # they correspond to. One .gcov file is produced for each source
+ # (or header) file containing code which was compiled to produce the
+ # .gcda files.
+ # Don't generate branch coverage (-b) because of a gcov issue that
+ # segfaults when both -i and -b are used (see
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84879).
+ "${GCOV}" -i -o "$(dirname ${gcda})" "${gcda}" &> "$gcov_log"
- local gcda="${COVERAGE_DIR}/$(dirname ${gcno_path})/$(basename ${gcno_path} .gcno).gcda"
- # If the gcda file was not found we skip generating coverage from the gcno
- # file.
- if [[ -f "$gcda" ]]; then
- # gcov expects both gcno and gcda files to be in the same directory.
- # We overcome this by copying the gcno to $COVERAGE_DIR where the gcda
- # files are expected to be.
- if [ ! -f "${COVERAGE_DIR}/${gcno_path}" ]; then
- mkdir -p "${COVERAGE_DIR}/$(dirname ${gcno_path})"
- cp "$ROOT/${gcno_path}" "${COVERAGE_DIR}/${gcno_path}"
- fi
- # Invoke gcov to generate a code coverage report with the flags:
- # -i Output gcov file in an intermediate text format.
- # The output is a single .gcov file per .gcda file.
- # No source code is required.
- # -o directory The directory containing the .gcno and
- # .gcda data files.
- # "${gcda"} The input file name. gcov is looking for data files
- # named after the input filename without its extension.
- # gcov produces files called <source file name>.gcov in the current
- # directory. These contain the coverage information of the source file
- # they correspond to. One .gcov file is produced for each source
- # (or header) file containing code which was compiled to produce the
- # .gcda files.
- # Don't generate branch coverage (-b) because of a gcov issue that
- # segfaults when both -i and -b are used (see
- # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84879).
- "${GCOV}" -i -o "$(dirname ${gcda})" "${gcda}" &> "$gcov_log"
-
- # Go through all the files that were created by the gcov command above
- # and append their content to the output .gcov file.
- #
- # For each source file gcov outputs to stdout something like this:
- #
- # File 'examples/cpp/hello-lib.cc'
- # Lines executed:100.00% of 8
- # Creating 'hello-lib.cc.gcov'
- #
- # We grep the names of the files that were created from that output.
- cat "$gcov_log" | grep "Creating" | cut -d " " -f 2 | cut -d"'" -f2 | \
- while read gcov_file; do
- echo "Processing $gcov_file"
- cat "$gcov_file" >> "$output_file"
- # Remove the intermediate gcov file because it is not useful anymore.
- rm -f "$gcov_file"
- done
+ # Go through all the files that were created by the gcov command above
+ # and append their content to the output .gcov file.
+ #
+ # For each source file gcov outputs to stdout something like this:
+ #
+ # File 'examples/cpp/hello-lib.cc'
+ # Lines executed:100.00% of 8
+ # Creating 'hello-lib.cc.gcov'
+ #
+ # We grep the names of the files that were created from that output.
+ cat "$gcov_log" | grep "Creating" | cut -d " " -f 2 | cut -d"'" -f2 | \
+ while read gcov_file; do
+ echo "Processing $gcov_file"
+ cat "$gcov_file" >> "$output_file"
+ # Remove the intermediate gcov file because it is not useful anymore.
+ rm -f "$gcov_file"
+ done
+ fi
fi
- done
+ done < "${COVERAGE_MANIFEST}"
}
function main() {