Skip to content

Commit

Permalink
perf(build): share precompiled headers for all targets
Browse files Browse the repository at this point in the history
Our precompiled header setup has a few problems:

* Some libraries, such as quick-lint-js-tool-lib, are not built with
  precompiled headers. This slows down incremental builds.
* Some executables, such as the benchmarks, get their own precompiled
  headers. This slows down clean builds and also bloats disk usage.

Fix these problems by building at most two precompiled headers (one for
quick-lint-js-test and one for everything else) and using them for all
quick-lint-js targets (quick_lint_js_add_library and
quick_lint_js_add_executable).

Development clean build of quick-lint-js and quick-lint-js-test:

    $ hyperfine --warmup=1 --prepare='rm -rf build && ./configure build' 'ninja -C build quick-lint-js-test quick-lint-js'
    Before:
    Time (mean ± σ):     12.686 s ±  0.068 s    [User: 95.302 s, System: 7.395 s]
    Range (min … max):   12.620 s … 12.861 s    10 runs
    After:
    Time (mean ± σ):     12.326 s ±  0.095 s    [User: 84.436 s, System: 7.015 s]
    Range (min … max):   12.238 s … 12.577 s    10 runs

CI approximation (clean build, 2 cores, builds benchmarks and Visual
Studio Code extension):

    $ hyperfine --warmup=1 --prepare='rm -rf build && ./configure build' 'ninja -C build -j2'
    Before:
    Time (mean ± σ):     63.348 s ±  0.087 s    [User: 116.393 s, System: 8.127 s]
    Range (min … max):   63.189 s … 63.474 s    10 runs
    After:
    Time (mean ± σ):     48.508 s ±  0.030 s    [User: 89.685 s, System: 6.250 s]
    Range (min … max):   48.449 s … 48.552 s    10 runs

Benchmarks performed on my Apple M1 laptop with Clang 16.
  • Loading branch information
strager committed Sep 11, 2023
1 parent 8e1f4c6 commit 09ae31a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
26 changes: 26 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,32 @@ find_package(PythonInterp 3.7)

find_package(PythonInterp 3) # Force Python 3 (instead of Python 2).

# quick-lint-js-precompiled-headers is used by quick_lint_js_add_executable and
# quick_lint_js_add_library.
include(QuickLintJSTarget)
find_package(Threads REQUIRED)
quick_lint_js_add_library(
quick-lint-js-precompiled-headers
STATIC
website/wasm/empty.cpp
)
target_link_libraries(
quick-lint-js-precompiled-headers
PUBLIC
Threads::Threads
simdjson
)
if (QUICK_LINT_JS_PRECOMPILE_HEADERS)
target_precompile_headers(
quick-lint-js-precompiled-headers
PUBLIC
<cmath>
<cstring>
<simdjson.h>
<string>
)
endif ()

# 'tools' must come first because it optionally defines targets. Other
# CMakeLists.txt files detect the presence of these targets.
add_subdirectory(tools)
Expand Down
22 changes: 22 additions & 0 deletions cmake/QuickLintJSTarget.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ function (quick_lint_js_add_executable TARGET)
PRIVATE
"${QUICK_LINT_JS_CXX_COMPILER_OPTIONS}"
)
if ("${TARGET}" STREQUAL quick-lint-js-test OR
"${TARGET}" STREQUAL quick-lint-js-test-lex-unicode)
# HACK(strager): Tests have their own precompiled headers.
else ()
quick_lint_js_use_default_precompiled_headers("${TARGET}")
endif ()
endfunction ()

function (quick_lint_js_add_library TARGET)
Expand All @@ -20,6 +26,22 @@ function (quick_lint_js_add_library TARGET)
PRIVATE
"${QUICK_LINT_JS_CXX_COMPILER_OPTIONS}"
)
if ("${TARGET}" STREQUAL quick-lint-js-precompiled-headers)
# Don't use PCH when building PCH.
else ()
quick_lint_js_use_default_precompiled_headers("${TARGET}")
endif ()
endfunction ()

function (quick_lint_js_use_default_precompiled_headers TARGET)
if (QUICK_LINT_JS_PRECOMPILE_HEADERS)
target_link_libraries("${TARGET}" PRIVATE quick-lint-js-precompiled-headers)
target_precompile_headers(
"${TARGET}"
REUSE_FROM
quick-lint-js-precompiled-headers
)
endif ()
endfunction ()

# quick-lint-js finds bugs in JavaScript programs.
Expand Down
10 changes: 0 additions & 10 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -475,16 +475,6 @@ endif ()
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
target_link_libraries(quick-lint-js-lib PUBLIC kvm)
endif ()
if (QUICK_LINT_JS_PRECOMPILE_HEADERS)
target_precompile_headers(
quick-lint-js-lib
PUBLIC
<cmath>
<cstring>
<simdjson.h>
<string>
)
endif ()

if (QUICK_LINT_JS_FEATURE_DEBUG_SERVER)
target_compile_definitions(
Expand Down

0 comments on commit 09ae31a

Please sign in to comment.