Commit cef6425bcac678157f58e9eafabb7e63c5831d18

Authored by Jay Berkenbilt
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.
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 &quot; build shared libraries: ${BUILD_SHARED_LIBS}&quot;)
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
... ...
... ... @@ -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=&quot;-fsanitize=address -fsanitize=undefined&quot; \
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($_))
... ...