perf: speed up C++ core, add benchmark platform with golden master - #24
Open
VincentGuyader wants to merge 14 commits into
Open
perf: speed up C++ core, add benchmark platform with golden master#24VincentGuyader wants to merge 14 commits into
VincentGuyader wants to merge 14 commits into
Conversation
added 14 commits
June 18, 2026 11:51
Drop the deprecated C++11 specification (R 4.6 builds C++17 by default), set LazyDataCompression to xz to shrink the lazy-load DB, point URL and BugReports at the current repository, and declare the test tooling (testthat, covr, mockery) under Suggests.
as_bitmap() relies on magick::image_data(), which was used but never
imported, so collage() and the histograms only worked when {magick} was
attached. tiles() extracted bitmaps via [[, which now yields 3-channel
RGB for opaque JPEGs, breaking the alpha lookup; force rgba extraction so
tiles stay 4-channel as the C++ engine expects. Regenerate docs/NAMESPACE
with roxygen2 (image_data import, _PACKAGE doc).
guides(colour = FALSE) has been deprecated since ggplot2 3.3.4.
Cover every exported function plus the C++ engine; network helpers (scrap/npages/tiles_animals) and shinycollage() are exercised through mocked bindings so the suite stays offline and never launches an app.
The R-CMD-check and test-coverage workflow files exist locally but can not be pushed with the current token (missing workflow OAuth scope) ; they will be pushed separately.
Per-stage timings of the collage() pipeline over 6 scenarios, plus an md5 golden master of every raw mosaic so C++ changes can be checked for byte-identical output. Includes the measured baseline results.
…loop Convert the base red/green/blue raw vectors to double once instead of nbase times per block, and accumulate block sums as integers (exact for sums of bytes). Measured 2.1x on the find_best_tiles stage across bases of 400 to 4000 tiles, byte-identical output.
Reorder the copy loops so writes to the output are sequential per pixel row instead of strided per tile, and compute offsets in R_xlen_t so mosaics over 2^31 bytes do not overflow int. Measured 1.05-1.29x on the assembly stage, byte-identical output.
Aligns Makevars with the RcppParallel skeleton and with Makevars.win. RcppParallelLibs() expands to nothing on Linux (verified) but provides the -ltbb flags required on macOS.
…U make The Makevars RcppParallelLibs() line uses GNU extensions, which R CMD check flags unless SystemRequirements declares GNU make.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Performance work on the C++ core, a reproducible benchmark platform with a golden master, and a build portability fix.
Benchmark platform (
dev/bench/)Rscript dev/bench/bench_collage.Rmeasures 6 scenarios (sources 200 to 1500 px, bases samples/kittens/emojis, block sizes 7 to 25) with a per-stage breakdown of thecollage()pipeline, and records an md5 golden master of every raw mosaic.--checkverifies byte-identical output after any C++ change. Not shipped (^dev$in.Rbuildignore).Optimizations (verified byte-identical on all 6 golden scenarios)
find_best_tiles: hoist base color conversion out of the search loop. The raw->double conversion of the base red/green/blue vectors was redonenbasetimes per block. Converting once upfront (plus exact integer accumulation of block sums) gives a measured 2.1x on this stage, stable across bases of 400 to 4000 tiles (e.g. 84300 blocks x 4000 tiles: 0.278 s -> 0.131 s).collage_impl: sequential writes. The copy loops were writing tile-by-tile with strided jumps of4*width*sizebytes between rows; reordering to fill each output pixel row sequentially gives 1.05x to 1.29x on the assembly stage (1.29x on a 202 MB mosaic).collage_impl:R_xlen_toffsets. Offsets were computed inintand overflow beyond 2 GiB of mosaic (reachable: a 5000 px photo atsize = 10with 50 px tiles). Now 64-bit.End-to-end,
collage()remains dominated by the {magick} conversions (image_read()of the final bitmap is up to ~85 % of total on large outputs); that cost is outside this package. Numbers and analysis indev/bench/README.mdanddev/bench/results/.Build fix
src/Makevarsnow uses the canonical RcppParallel link line (RcppParallelLibs()), asMakevars.winalready did. On Linux it expands to nothing (verified); on macOS it supplies the required-ltbbflags.SystemRequirements: GNU makeadded accordingly (the line uses$(shell)), which keepsR CMD check --as-cranfree of the GNU-extension warning.Resource findings (documented, no code change)
(tile_size/size)^2vs the source: 1500 px atsize = 5with 50 px tiles is a ~840 MB rgba image, which ImageMagick refuses under default cache policy (cache resources exhausted; boundary measured at ~414 MB OK / ~840 MB fail). RaisingMAGICK_MEMORY_LIMITand friends makes it build in ~3.5 s (2.6 GB peak RSS). Documented indev/bench/README.md.RcppParallel::setThreadOptions(numThreads = ...).Verification
R CMD check --no-manual --as-cran: same status asmaster(the 2 pre-existing NOTEs: non-portable-mno-omit-leaf-frame-pointerflag injected by Ubuntu's Makeconf, and incoming-feasibility remarks). No new WARNING/NOTE.-Wall -Wextraclean on touched files, TBB lambda thread-safety checked).Note on CI workflows
This branch also carries the local modernization stack (metadata, magick compat fix, testthat suite, examples) that had never been pushed. The two GitHub Actions workflow files (
R-CMD-check.yaml,test-coverage.yaml) are included in the final commit (they required a token refresh with theworkflowscope, hence the separate commit).