Commit cef6425bcac678157f58e9eafabb7e63c5831d18
1 parent
da71dc6f
Disable QTC inside the library by default (fixes #714)
This results in measurable performance improvements to packaged binary libqpdf distributions. QTC remains available for library users and is still selectively enabled in CI.
Showing
9 changed files
with
71 additions
and
11 deletions
CMakeLists.txt
| ... | ... | @@ -43,6 +43,9 @@ CMAKE_DEPENDENT_OPTION( |
| 43 | 43 | GENERATE_AUTO_JOB "Automatically regenerate job files" OFF |
| 44 | 44 | "NOT MAINTAINER_MODE" ON) |
| 45 | 45 | CMAKE_DEPENDENT_OPTION( |
| 46 | + ENABLE_QTC "Enable QTC test coverage" OFF | |
| 47 | + "NOT MAINTAINER_MODE" ON) | |
| 48 | +CMAKE_DEPENDENT_OPTION( | |
| 46 | 49 | SHOW_FAILED_TEST_OUTPUT "Show qtest output on failure" OFF |
| 47 | 50 | "NOT CI_MODE" ON) |
| 48 | 51 | |
| ... | ... | @@ -110,8 +113,15 @@ endif() |
| 110 | 113 | |
| 111 | 114 | add_compile_definitions($<$<COMPILE_LANGUAGE:CXX>:POINTERHOLDER_TRANSITION=4>) |
| 112 | 115 | |
| 116 | +if(ENABLE_QTC) | |
| 117 | + set(ENABLE_QTC_ARG) | |
| 118 | +else() | |
| 119 | + add_compile_definitions(QPDF_DISABLE_QTC=1) | |
| 120 | + set(ENABLE_QTC_ARG --disable-tc) | |
| 121 | +endif() | |
| 122 | + | |
| 113 | 123 | enable_testing() |
| 114 | -set(RUN_QTEST perl ${qpdf_SOURCE_DIR}/run-qtest) | |
| 124 | +set(RUN_QTEST perl ${qpdf_SOURCE_DIR}/run-qtest ${ENABLE_QTC_ARG}) | |
| 115 | 125 | |
| 116 | 126 | if(WIN32) |
| 117 | 127 | find_program(COPY_COMMAND NAMES cp copy) |
| ... | ... | @@ -335,6 +345,7 @@ message(STATUS " build shared libraries: ${BUILD_SHARED_LIBS}") |
| 335 | 345 | message(STATUS " build static libraries: ${BUILD_STATIC_LIBS}") |
| 336 | 346 | message(STATUS " build manual: ${BUILD_DOC}") |
| 337 | 347 | message(STATUS " compiler warnings are errors: ${WERROR}") |
| 348 | +message(STATUS " QTC test coverage: ${ENABLE_QTC}") | |
| 338 | 349 | message(STATUS " system: ${CPACK_SYSTEM_NAME}") |
| 339 | 350 | message(STATUS "") |
| 340 | 351 | message(STATUS "*** Options Summary ***") | ... | ... |
ChangeLog
| 1 | +2022-08-07 Jay Berkenbilt <ejb@ql.org> | |
| 2 | + | |
| 3 | + * Add new build configuration option ENABLE_QTC, which is off by | |
| 4 | + default when not running in MAINTAINER_MODE. When this is off, | |
| 5 | + QTC coverage calls sprinkled throughout the qpdf source code are | |
| 6 | + compiled out for increased performance. See "Build Options" in the | |
| 7 | + manual for a discussion. Fixes #714. | |
| 8 | + | |
| 1 | 9 | 2022-08-06 Jay Berkenbilt <ejb@ql.org> |
| 2 | 10 | |
| 3 | 11 | * Added by m-holger: QPDF::getObject() method as a simpler form of | ... | ... |
TODO
| ... | ... | @@ -4,14 +4,9 @@ Next |
| 4 | 4 | |
| 5 | 5 | Before Release: |
| 6 | 6 | |
| 7 | -* Improve performance around QTC | |
| 8 | - * Make it possible to compile it out and deal with it in the tests | |
| 9 | - * Make sure at least some CI test is run with coverage enabled | |
| 10 | - * Cache environment variables | |
| 11 | - * Remove coverage cases for things that are heavily exercised or are | |
| 12 | - in critical paths | |
| 13 | 7 | * Make ./performance_check usable by other people by having published |
| 14 | 8 | files to use for testing. |
| 9 | + * https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/pdfstandards/pdf/PDF32000_2008.pdf | |
| 15 | 10 | * Evaluate issues tagged with `next` |
| 16 | 11 | * Stay on top of https://github.com/pikepdf/pikepdf/pull/315 |
| 17 | 12 | ... | ... |
build-scripts/test-sanitizers
| ... | ... | @@ -10,7 +10,8 @@ env CFLAGS="-fsanitize=address -fsanitize=undefined" \ |
| 10 | 10 | CC=clang CXX=clang++ \ |
| 11 | 11 | cmake -S . -B build \ |
| 12 | 12 | -DCI_MODE=1 -DBUILD_SHARED_LIBS=0 -DCMAKE_BUILD_TYPE=Debug \ |
| 13 | - -DREQUIRE_CRYPTO_OPENSSL=1 -DREQUIRE_CRYPTO_GNUTLS=1 | |
| 13 | + -DREQUIRE_CRYPTO_OPENSSL=1 -DREQUIRE_CRYPTO_GNUTLS=1 \ | |
| 14 | + -DENABLE_QTC=1 | |
| 14 | 15 | cmake --build build -j$(nproc) -- -k |
| 15 | 16 | cd build |
| 16 | 17 | # libtests automatically runs with all crypto providers. | ... | ... |
include/qpdf/QTC.hh
| ... | ... | @@ -24,10 +24,24 @@ |
| 24 | 24 | |
| 25 | 25 | #include <qpdf/DLL.h> |
| 26 | 26 | |
| 27 | +// Defining QPDF_DISABLE_QTC will effectively compile out any QTC::TC | |
| 28 | +// calls in any code that includes this file, but QTC will still be | |
| 29 | +// built into the library. That way, it is possible to build and | |
| 30 | +// package qpdf with QPDF_DISABLE_QTC while still making QTC::TC | |
| 31 | +// available to end users. | |
| 32 | + | |
| 27 | 33 | namespace QTC |
| 28 | 34 | { |
| 29 | 35 | QPDF_DLL |
| 30 | - void TC(char const* const scope, char const* const ccase, int n = 0); | |
| 36 | + void TC_real(char const* const scope, char const* const ccase, int n = 0); | |
| 37 | + | |
| 38 | + inline void | |
| 39 | + TC(char const* const scope, char const* const ccase, int n = 0) | |
| 40 | + { | |
| 41 | +#ifndef QPDF_DISABLE_QTC | |
| 42 | + TC_real(scope, ccase, n); | |
| 43 | +#endif // QPDF_DISABLE_QTC | |
| 44 | + } | |
| 31 | 45 | }; // namespace QTC |
| 32 | 46 | |
| 33 | 47 | #endif // QTC_HH | ... | ... |
libqpdf/QTC.cc
| ... | ... | @@ -13,7 +13,7 @@ tc_active(char const* const scope) |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | void |
| 16 | -QTC::TC(char const* const scope, char const* const ccase, int n) | |
| 16 | +QTC::TC_real(char const* const scope, char const* const ccase, int n) | |
| 17 | 17 | { |
| 18 | 18 | static std::map<std::string, bool> active; |
| 19 | 19 | auto is_active = active.find(scope); | ... | ... |
manual/installation.rst
| ... | ... | @@ -257,6 +257,16 @@ CHECK_SIZES |
| 257 | 257 | that ensures an exact match between classes in ``sizes.cc`` and |
| 258 | 258 | classes in the library's public API. This option requires Python 3. |
| 259 | 259 | |
| 260 | +ENABLE_QTC | |
| 261 | + This is off by default, except in maintainer mode. When off, | |
| 262 | + ``QTC::TC`` calls are compiled out by having ``QTC::TC`` be an empty | |
| 263 | + inline function. The underlying ``QTC::TC`` remains in the library, | |
| 264 | + so it is possible to build and package the qpdf library with | |
| 265 | + ``ENABLE_QTC`` turned off while still allowing developer code to use | |
| 266 | + ``QTC::TC`` if desired. If you are modifying qpdf code, it's a good | |
| 267 | + idea to have this on for more robust automated testing. Otherwise, | |
| 268 | + there's no reason to have it on. | |
| 269 | + | |
| 260 | 270 | GENERATE_AUTO_JOB |
| 261 | 271 | Some qpdf source files are automatically generated from |
| 262 | 272 | :file:`job.yml` and the CLI documentation. If you are adding new |
| ... | ... | @@ -297,6 +307,8 @@ MAINTAINER_MODE |
| 297 | 307 | |
| 298 | 308 | - ``CHECK_SIZES`` |
| 299 | 309 | |
| 310 | + - ``ENABLE_QTC`` | |
| 311 | + | |
| 300 | 312 | - ``GENERATE_AUTO_JOB`` |
| 301 | 313 | |
| 302 | 314 | - ``WERROR`` | ... | ... |
manual/release-notes.rst
| ... | ... | @@ -7,6 +7,12 @@ For a detailed list of changes, please see the file |
| 7 | 7 | :file:`ChangeLog` in the source distribution. |
| 8 | 8 | |
| 9 | 9 | 11.0.0 |
| 10 | + - Performance improvements | |
| 11 | + | |
| 12 | + - Many performance enhancements have been added. In developer | |
| 13 | + performance benchmarks, gains on the order of 20% have been | |
| 14 | + observed. | |
| 15 | + | |
| 10 | 16 | - Replacement of ``PointerHolder`` with ``std::shared_ptr`` |
| 11 | 17 | |
| 12 | 18 | - The qpdf-specific ``PointerHolder`` smart pointer implementation |
| ... | ... | @@ -231,6 +237,14 @@ For a detailed list of changes, please see the file |
| 231 | 237 | - The qpdf source code is now formatted automatically with |
| 232 | 238 | ``clang-format``. See :ref:`code-formatting` for information. |
| 233 | 239 | |
| 240 | + - Test coverage with ``QTC`` is enabled during development but | |
| 241 | + compiled out of distributed qpdf binaries by default. This | |
| 242 | + results in a significant performance improvement, especially on | |
| 243 | + Windows. ``QTC::TC`` is still available in the library and is | |
| 244 | + still usable by end user code even though calls to it made | |
| 245 | + internally by the library are turned off. Internally, there is | |
| 246 | + some additional caching to reduce the overhead of repeatedly | |
| 247 | + reading environment variables at runtime. | |
| 234 | 248 | |
| 235 | 249 | 10.6.3: March 8, 2022 |
| 236 | 250 | - Announcement of upcoming change: | ... | ... |
run-qtest
| ... | ... | @@ -13,6 +13,7 @@ my $code = undef; |
| 13 | 13 | my @bin = (); |
| 14 | 14 | my $color = undef; |
| 15 | 15 | my $show_on_failure = 0; |
| 16 | +my $disable_tc = 0; | |
| 16 | 17 | my @tc = (); |
| 17 | 18 | |
| 18 | 19 | if ($^O =~ m/^MSWin32|msys$/) |
| ... | ... | @@ -51,6 +52,10 @@ while (@ARGV) |
| 51 | 52 | usage() unless @ARGV; |
| 52 | 53 | $show_on_failure = cmake_bool(shift(@ARGV)); |
| 53 | 54 | } |
| 55 | + elsif ($arg eq '--disable-tc') | |
| 56 | + { | |
| 57 | + $disable_tc = 1; | |
| 58 | + } | |
| 54 | 59 | elsif ($arg eq '--tc') |
| 55 | 60 | { |
| 56 | 61 | usage() unless @ARGV; |
| ... | ... | @@ -94,7 +99,7 @@ push(@cmd, |
| 94 | 99 | "-datadir", "$code/qtest", |
| 95 | 100 | "-junit-suffix", basename($code)); |
| 96 | 101 | |
| 97 | -if (scalar(@tc)) | |
| 102 | +if (scalar(@tc) && (! $disable_tc)) | |
| 98 | 103 | { |
| 99 | 104 | my @tc_srcs = map { |
| 100 | 105 | File::Spec->abs2rel(abs_path($_)) | ... | ... |