Date: 2025-11-26

# Benchmarking PLS1 Implementations

#### Frédéric Bertrand

#### 2025-11-26

    library(bigPLSR)
    library(bigmemory)
    library(bench)
    set.seed(123)

## Overview

The unified `pls_fit()` interface now drives both the dense and streaming implementations of single-response partial least squares regression. This vignette revisits the benchmarking workflow with the modern API and introduces two complementary perspectives:

1. Internal comparisons that contrast the dense (in-memory) and streaming (big-memory) backends of `pls_fit()`.
2. External references recorded against popular packages such as `pls` and `mixOmics`. These results are stored in the package to keep the vignette lightweight while still documenting performance relative to the wider ecosystem.

The chunks tagged with `eval = LOCAL` are only executed when the environment variable `LOCAL` is set to `TRUE`, allowing CRAN checks to skip the more time-consuming benchmarks.

## Simulated data

We create a synthetic regression problem with a modest latent structure and keep both dense and big-memory versions of the predictors and response so they can be reused in the benchmarking chunks.

Here is an example with `n=4000` en `p=50`

    n <- 1500
    p <- 80
    ncomp <- 6

    X <- bigmemory::big.matrix(nrow = n, ncol = p, type = "double")
    X[,] <- matrix(rnorm(n * p), nrow = n)

    y_vec <- scale(X[,] %*% rnorm(p) + rnorm(n))

    y <- bigmemory::big.matrix(nrow = n, ncol = 1, type = "double")
    y[,] <- y_vec

    X[1:6, 1:6]
    #>             [,1]       [,2]        [,3]       [,4]       [,5]       [,6]
    #> [1,] -0.56047565 -0.8209867 -0.15030748  0.8343715 -0.6992281  0.3500025
    #> [2,] -0.23017749 -0.3072572 -0.32775713 -0.6984039  0.9964515  0.8144417
    #> [3,]  1.55870831 -0.9020980 -1.44816529  1.3092405 -0.6927454 -0.5166661
    #> [4,]  0.07050839  0.6270687 -0.69728458 -0.9801776 -0.1034830 -2.6922644
    #> [5,]  0.12928774  1.1203550  2.59849023  0.7479851  0.6038661 -1.0969546
    #> [6,]  1.71506499  2.1272136 -0.03741501  1.2577966 -0.6080450 -1.2554751
    y[1:6,]
    #> [1]  0.66723250  0.66189719 -0.77458416  0.07452428  0.28174414  0.15756565

## Internal benchmarks

The following chunk compares dense vs. streaming fits for both SIMPLS and NIPALS. The dense backend receives base R matrices, while the streaming backend consumes the `big.matrix` objects directly.

    internal_bench <- bench::mark(
      dense_simpls = pls_fit(as.matrix(X[]), y_vec, ncomp = ncomp,
                             backend = "arma", algorithm = "simpls"),
      streaming_simpls = pls_fit(X, y, ncomp = ncomp, backend = "bigmem",
                                 algorithm = "simpls", chunk_size = 512L),
      dense_nipals = pls_fit(as.matrix(X[]), y_vec, ncomp = ncomp,
                             backend = "arma", algorithm = "nipals"),
      streaming_nipals = pls_fit(X, y, ncomp = ncomp, backend = "bigmem",
                                 algorithm = "nipals", chunk_size = 512L),
      dense_kernelpls = pls_fit(as.matrix(X[]), y_vec, ncomp = ncomp,
                             backend = "arma", algorithm = "kernelpls"),
      streaming_kernelpls = pls_fit(X, y, ncomp = ncomp, backend = "bigmem",
                                 algorithm = "kernelpls", chunk_size = 512L),
      dense_widekernelpls = pls_fit(as.matrix(X[]), y_vec, ncomp = ncomp,
                             backend = "arma", algorithm = "widekernelpls"),
      streaming_widekernelpls = pls_fit(X, y, ncomp = ncomp, backend = "bigmem",
                                 algorithm = "widekernelpls", chunk_size = 512L),
      iterations = 20,
      check = FALSE
    )
    internal_bench_res <-internal_bench[,2:5]
    internal_bench_res <- as.matrix(internal_bench_res)
    rownames(internal_bench_res) <- names(internal_bench$expression)

    dotchart(internal_bench_res[,2], labels=rownames(internal_bench_res),xlab="median_time_s")

    dotchart(internal_bench_res[,3], labels=rownames(internal_bench_res),xlab="itr_per_sec")

    dotchart(internal_bench_res[,4], labels=rownames(internal_bench_res),xlab="mem_alloc_bytes")

The results highlight the trade-off between throughput and memory usage: SIMPLS shines on dense matrices, whereas the streaming backend scales to larger-than-memory inputs thanks to block processing.

## External references

To avoid heavy dependencies at build time we ship a pre-computed benchmark dataset that contrasts `bigPLSR` with implementations from the `pls` and `mixOmics` packages. The dataset was generated with the helper script stored in `inst/scripts/external_pls_benchmarks.R`.

    data("external_pls_benchmarks", package = "bigPLSR")
    sub_pls1 <- subset(external_pls_benchmarks,task=="pls1" & !algorithm=="widekernelpls")
    sub_pls1$n <- factor(sub_pls1$n)
    sub_pls1$p <- factor(sub_pls1$p)
    sub_pls1$q <- factor(sub_pls1$q)
    sub_pls1$ncomp <- factor(sub_pls1$ncomp)
    replications(~package+algorithm+task+n+p+ncomp,data=sub_pls1)
    #> $package
    #> [1] 24
    #>
    #> $algorithm
    #> [1] 32
    #>
    #> $task
    #> [1] 96
    #>
    #> $n
    #> [1] 48
    #>
    #> $p
    #> [1] 48
    #>
    #> $ncomp
    #> ncomp
    #>   1   3  10 100
    #>  24  24  36  12

    sub_pls1_wide <- subset(external_pls_benchmarks,external_pls_benchmarks$task=="pls1" & algorithm=="widekernelpls")
    sub_pls1_wide$n <- factor(sub_pls1_wide$n)
    sub_pls1_wide$p <- factor(sub_pls1_wide$p)
    sub_pls1_wide$q <- factor(sub_pls1_wide$q)
    sub_pls1_wide$ncomp <- factor(sub_pls1_wide$ncomp)
    replications(~package+algorithm+task+n+p+ncomp,data=sub_pls1_wide)
    #> $package
    #> [1] 8
    #>
    #> $algorithm
    #> [1] 32
    #>
    #> $task
    #> [1] 32
    #>
    #> $n
    #> [1] 16
    #>
    #> $p
    #> [1] 16
    #>
    #> $ncomp
    #> ncomp
    #>   1   3  10 100
    #>   8   8  12   4

    sub_pls2 <- subset(external_pls_benchmarks,external_pls_benchmarks$task=="pls2" & !algorithm=="widekernelpls")
    sub_pls2$n <- factor(sub_pls2$n)
    sub_pls2$p <- factor(sub_pls2$p)
    sub_pls2$q <- factor(sub_pls2$q)
    sub_pls2$ncomp <- factor(sub_pls2$ncomp)
    replications(~package+algorithm+task+n+p+ncomp,data=sub_pls2)
    #> $package
    #> [1] 48
    #>
    #> $algorithm
    #> [1] 64
    #>
    #> $task
    #> [1] 192
    #>
    #> $n
    #> [1] 96
    #>
    #> $p
    #> [1] 96
    #>
    #> $ncomp
    #> ncomp
    #>  1  3 10
    #> 48 48 96

    sub_pls2_wide <- subset(external_pls_benchmarks,external_pls_benchmarks$task=="pls2" & algorithm=="widekernelpls")
    sub_pls2_wide$n <- factor(sub_pls2_wide$n)
    sub_pls2_wide$p <- factor(sub_pls2_wide$p)
    sub_pls2_wide$q <- factor(sub_pls2_wide$q)
    sub_pls2_wide$ncomp <- factor(sub_pls2_wide$ncomp)
    replications(~package+algorithm+task+n+p+ncomp,data=sub_pls2_wide)
    #> $package
    #> [1] 16
    #>
    #> $algorithm
    #> [1] 64
    #>
    #> $task
    #> [1] 64
    #>
    #> $n
    #> [1] 32
    #>
    #> $p
    #> [1] 32
    #>
    #> $ncomp
    #> ncomp
    #>  1  3 10
    #> 16 16 32

    sub_pls1
    #>     task algorithm            package median_time_s  itr_per_sec
    #> 1   pls1    simpls      bigPLSR_dense  0.0060451836  165.1562621
    #> 2   pls1    simpls bigPLSR_big.memory  0.0035867620  275.9417591
    #> 3   pls1    simpls                pls  0.0020867360  469.9431634
    #> 4   pls1    simpls           mixOmics  0.0044788605  223.4486896
    #> 5   pls1 kernelpls      bigPLSR_dense  0.0441235030   22.6636584
    #> 6   pls1 kernelpls bigPLSR_big.memory  0.0005215200 1733.6289782
    #> 7   pls1 kernelpls                pls  0.0021023160  475.5957998
    #> 8   pls1 kernelpls           mixOmics  0.0044129530  224.0172938
    #> 13  pls1    nipals      bigPLSR_dense  0.0007704311 1208.7122974
    #> 14  pls1    nipals bigPLSR_big.memory  0.0064723010  154.6317423
    #> 15  pls1    nipals                pls  0.0023130355  423.5614303
    #> 16  pls1    nipals           mixOmics  0.0045207831  221.5220634
    #> 17  pls1    simpls      bigPLSR_dense  0.0061238625  160.2659625
    #> 18  pls1    simpls bigPLSR_big.memory  0.0034934051  280.9346862
    #> 19  pls1    simpls                pls  0.0026201049  378.4570550
    #> 20  pls1    simpls           mixOmics  0.0081250110  122.0214629
    #> 21  pls1 kernelpls      bigPLSR_dense  0.0459685031   21.7108564
    #> 22  pls1 kernelpls bigPLSR_big.memory  0.0011338961  885.9666822
    #> 23  pls1 kernelpls                pls  0.0026236720  383.4893703
    #> 24  pls1 kernelpls           mixOmics  0.0081293570  121.1046267
    #> 29  pls1    nipals      bigPLSR_dense  0.0017690270  544.4038157
    #> 30  pls1    nipals bigPLSR_big.memory  0.0063486451  155.6316749
    #> 31  pls1    nipals                pls  0.0032869700  308.6738445
    #> 32  pls1    nipals           mixOmics  0.0082580560  121.5590611
    #> 33  pls1    simpls      bigPLSR_dense  0.0062094295  160.3209005
    #> 34  pls1    simpls bigPLSR_big.memory  0.0035923790  275.3568879
    #> 35  pls1    simpls                pls  0.0046357060  207.3664119
    #> 36  pls1    simpls           mixOmics  0.0209913850   47.6021094
    #> 37  pls1 kernelpls      bigPLSR_dense  0.0498161890   20.0737957
    #> 38  pls1 kernelpls bigPLSR_big.memory  0.0032459290  301.8471240
    #> 39  pls1 kernelpls                pls  0.0047320150  211.2860747
    #> 40  pls1 kernelpls           mixOmics  0.0209948905   47.6736952
    #> 45  pls1    nipals      bigPLSR_dense  0.0047139545  211.8381858
    #> 46  pls1    nipals bigPLSR_big.memory  0.0065105130  153.5810813
    #> 47  pls1    nipals                pls  0.0074865180  132.9719814
    #> 48  pls1    nipals           mixOmics  0.0210122335   46.8847723
    #> 145 pls1    simpls      bigPLSR_dense  6.5033901315    0.1547340
    #> 146 pls1    simpls bigPLSR_big.memory  3.5608631200    0.2812449
    #> 147 pls1    simpls                pls  0.3611949530    2.9793809
    #> 148 pls1    simpls           mixOmics  0.4746793860    2.0961402
    #> 149 pls1 kernelpls      bigPLSR_dense  0.0888563070   11.0521410
    #> 150 pls1 kernelpls bigPLSR_big.memory  0.0596174030   16.5969947
    #> 151 pls1 kernelpls                pls  0.3368680336    3.1522969
    #> 152 pls1 kernelpls           mixOmics  0.4710328870    2.2186854
    #> 157 pls1    nipals      bigPLSR_dense  0.0818347905   12.0507715
    #> 158 pls1    nipals bigPLSR_big.memory  6.2263474941    0.1599221
    #> 159 pls1    nipals                pls  0.1974032740    5.0479061
    #> 160 pls1    nipals           mixOmics  0.2946449011    3.3824261
    #> 161 pls1    simpls      bigPLSR_dense  6.1359636295    0.1626558
    #> 162 pls1    simpls bigPLSR_big.memory  3.3408962340    0.2994953
    #> 163 pls1    simpls                pls  0.2738218415    3.2636860
    #> 164 pls1    simpls           mixOmics  0.7325085420    1.4078995
    #> 165 pls1 kernelpls      bigPLSR_dense  0.2181904176    4.6082604
    #> 166 pls1 kernelpls bigPLSR_big.memory  0.1305059521    7.7058833
    #> 167 pls1 kernelpls                pls  0.3852149671    2.6743926
    #> 168 pls1 kernelpls           mixOmics  0.7455238690    1.2945480
    #> 173 pls1    nipals      bigPLSR_dense  0.1886118900    5.1953353
    #> 174 pls1    nipals bigPLSR_big.memory  6.2367988861    0.1602238
    #> 175 pls1    nipals                pls  0.3296010500    3.0281963
    #> 176 pls1    nipals           mixOmics  0.5922050660    1.7045469
    #> 177 pls1    simpls      bigPLSR_dense  6.2095294170    0.1609821
    #> 178 pls1    simpls bigPLSR_big.memory  3.4807222855    0.2865378
    #> 179 pls1    simpls                pls  0.4312646910    2.2350247
    #> 180 pls1    simpls           mixOmics  1.7723871550    0.5695185
    #> 181 pls1 kernelpls      bigPLSR_dense  0.6455497560    1.5651878
    #> 182 pls1 kernelpls bigPLSR_big.memory  0.3514678876    2.7636579
    #> 183 pls1 kernelpls                pls  0.5371060476    1.8759850
    #> 184 pls1 kernelpls           mixOmics  1.8362041675    0.5476303
    #> 189 pls1    nipals      bigPLSR_dense  0.5208903835    1.9089468
    #> 190 pls1    nipals bigPLSR_big.memory  6.2764627576    0.1592679
    #> 191 pls1    nipals                pls  0.7559157085    1.3152253
    #> 192 pls1    nipals           mixOmics  1.6296500625    0.6067950
    #> 289 pls1    simpls      bigPLSR_dense  0.0062788220  158.3886973
    #> 290 pls1    simpls bigPLSR_big.memory  0.0041523160  235.3499445
    #> 291 pls1    simpls                pls  0.0049248995  202.1917049
    #> 292 pls1    simpls           mixOmics  0.0229660476   42.7499866
    #> 293 pls1 kernelpls      bigPLSR_dense  0.0506123269   19.4606804
    #> 294 pls1 kernelpls bigPLSR_big.memory  0.0033179866  299.1089816
    #> 295 pls1 kernelpls                pls  0.0049014065  202.4541097
    #> 296 pls1 kernelpls           mixOmics  0.0221207505   45.1716313
    #> 301 pls1    nipals      bigPLSR_dense  0.0047306620  210.7978021
    #> 302 pls1    nipals bigPLSR_big.memory  0.0066085235  148.0432944
    #> 303 pls1    nipals                pls  0.0079110935  126.1707804
    #> 304 pls1    nipals           mixOmics  0.0220015431   45.5108450
    #> 337 pls1    simpls      bigPLSR_dense  6.1752819530    0.1613928
    #> 338 pls1    simpls bigPLSR_big.memory  3.3039307570    0.3007239
    #> 339 pls1    simpls                pls  0.5349956956    1.9629343
    #> 340 pls1    simpls           mixOmics  1.6342236126    0.6042950
    #> 341 pls1 kernelpls      bigPLSR_dense  0.6289640670    1.5716088
    #> 342 pls1 kernelpls bigPLSR_big.memory  0.3496842645    2.7791228
    #> 343 pls1 kernelpls                pls  0.5294607366    1.9623568
    #> 344 pls1 kernelpls           mixOmics  1.6767431134    0.5890119
    #> 349 pls1    nipals      bigPLSR_dense  0.5095970975    1.9054646
    #> 350 pls1    nipals bigPLSR_big.memory  6.2690384570    0.1591941
    #> 351 pls1    nipals                pls  0.7049397730    1.3617341
    #> 352 pls1    nipals           mixOmics  1.5486491710    0.6395732
    #>     mem_alloc_bytes     n    p q ncomp
    #> 1            104720  1000  100 1     1
    #> 2            895872  1000  100 1     1
    #> 3           7479024  1000  100 1     1
    #> 4           7550384  1000  100 1     1
    #> 5          42461256  1000  100 1     1
    #> 6            821328  1000  100 1     1
    #> 7           7462504  1000  100 1     1
    #> 8           7550384  1000  100 1     1
    #> 13            14928  1000  100 1     1
    #> 14           830224  1000  100 1     1
    #> 15          8265304  1000  100 1     1
    #> 16          7550384  1000  100 1     1
    #> 17           107920  1000  100 1     3
    #> 18           899072  1000  100 1     3
    #> 19          7764576  1000  100 1     3
    #> 20         12407296  1000  100 1     3
    #> 21         42480456  1000  100 1     3
    #> 22           840528  1000  100 1     3
    #> 23          7720248  1000  100 1     3
    #> 24         12304368  1000  100 1     3
    #> 29            18128  1000  100 1     3
    #> 30           865424  1000  100 1     3
    #> 31         10122568  1000  100 1     3
    #> 32         12304368  1000  100 1     3
    #> 33           119120  1000  100 1    10
    #> 34           910272  1000  100 1    10
    #> 35          9013040  1000  100 1    10
    #> 36         28992768  1000  100 1    10
    #> 37         42547656  1000  100 1    10
    #> 38           907728  1000  100 1    10
    #> 39          8959992  1000  100 1    10
    #> 40         28992768  1000  100 1    10
    #> 45            29328  1000  100 1    10
    #> 46           988624  1000  100 1    10
    #> 47         16876368  1000  100 1    10
    #> 48         28992768  1000  100 1    10
    #> 145         8226320 10000 1000 1     1
    #> 146        88138272 10000 1000 1     1
    #> 147       722792304 10000 1000 1     1
    #> 148       651508960 10000 1000 1     1
    #> 149          282544 10000 1000 1     1
    #> 150        80194128 10000 1000 1     1
    #> 151       722624584 10000 1000 1     1
    #> 152       651508960 10000 1000 1     1
    #> 157          130128 10000 1000 1     1
    #> 158        80282224 10000 1000 1     1
    #> 159       802652584 10000 1000 1     1
    #> 160       651508960 10000 1000 1     1
    #> 161         8258320 10000 1000 1     3
    #> 162        88170272 10000 1000 1     3
    #> 163       725626656 10000 1000 1     3
    #> 164       986912144 10000 1000 1     3
    #> 165          474544 10000 1000 1     3
    #> 166        80386128 10000 1000 1     3
    #> 167       725179128 10000 1000 1     3
    #> 168       986912144 10000 1000 1     3
    #> 173          162128 10000 1000 1     3
    #> 174        80634224 10000 1000 1     3
    #> 175       965206648 10000 1000 1     3
    #> 176       986912144 10000 1000 1     3
    #> 177         8370320 10000 1000 1    10
    #> 178        88282272 10000 1000 1    10
    #> 179       738038720 10000 1000 1    10
    #> 180      2161313744 10000 1000 1    10
    #> 181         1146544 10000 1000 1    10
    #> 182        81058128 10000 1000 1    10
    #> 183       737488872 10000 1000 1    10
    #> 184      2161313744 10000 1000 1    10
    #> 189          274128 10000 1000 1    10
    #> 190        81866224 10000 1000 1    10
    #> 191      1536642048 10000 1000 1    10
    #> 192      2161313744 10000 1000 1    10
    #> 289          119120  1000  100 1    10
    #> 290          910272  1000  100 1    10
    #> 291         9013040  1000  100 1    10
    #> 292        28992768  1000  100 1    10
    #> 293        42547656  1000  100 1    10
    #> 294          907728  1000  100 1    10
    #> 295         8959992  1000  100 1    10
    #> 296        28992768  1000  100 1    10
    #> 301           29328  1000  100 1    10
    #> 302          988624  1000  100 1    10
    #> 303        16876368  1000  100 1    10
    #> 304        28992768  1000  100 1    10
    #> 337         8370320 10000 1000 1   100
    #> 338        88282272 10000 1000 1   100
    #> 339       738038720 10000 1000 1   100
    #> 340      2161313744 10000 1000 1   100
    #> 341         1146544 10000 1000 1   100
    #> 342        81058128 10000 1000 1   100
    #> 343       737488872 10000 1000 1   100
    #> 344      2161313744 10000 1000 1   100
    #> 349          274128 10000 1000 1   100
    #> 350        81866224 10000 1000 1   100
    #> 351      1536642048 10000 1000 1   100
    #> 352      2161313744 10000 1000 1   100
    #>                                         notes
    #> 1        Run via pls_fit() with dense backend
    #> 2   Run via pls_fit() with big.memory backend
    #> 3                    Requires the pls package
    #> 4               Requires the mixOmics package
    #> 5        Run via pls_fit() with dense backend
    #> 6   Run via pls_fit() with big.memory backend
    #> 7                    Requires the pls package
    #> 8               Requires the mixOmics package
    #> 13       Run via pls_fit() with dense backend
    #> 14  Run via pls_fit() with big.memory backend
    #> 15                   Requires the pls package
    #> 16              Requires the mixOmics package
    #> 17       Run via pls_fit() with dense backend
    #> 18  Run via pls_fit() with big.memory backend
    #> 19                   Requires the pls package
    #> 20              Requires the mixOmics package
    #> 21       Run via pls_fit() with dense backend
    #> 22  Run via pls_fit() with big.memory backend
    #> 23                   Requires the pls package
    #> 24              Requires the mixOmics package
    #> 29       Run via pls_fit() with dense backend
    #> 30  Run via pls_fit() with big.memory backend
    #> 31                   Requires the pls package
    #> 32              Requires the mixOmics package
    #> 33       Run via pls_fit() with dense backend
    #> 34  Run via pls_fit() with big.memory backend
    #> 35                   Requires the pls package
    #> 36              Requires the mixOmics package
    #> 37       Run via pls_fit() with dense backend
    #> 38  Run via pls_fit() with big.memory backend
    #> 39                   Requires the pls package
    #> 40              Requires the mixOmics package
    #> 45       Run via pls_fit() with dense backend
    #> 46  Run via pls_fit() with big.memory backend
    #> 47                   Requires the pls package
    #> 48              Requires the mixOmics package
    #> 145      Run via pls_fit() with dense backend
    #> 146 Run via pls_fit() with big.memory backend
    #> 147                  Requires the pls package
    #> 148             Requires the mixOmics package
    #> 149      Run via pls_fit() with dense backend
    #> 150 Run via pls_fit() with big.memory backend
    #> 151                  Requires the pls package
    #> 152             Requires the mixOmics package
    #> 157      Run via pls_fit() with dense backend
    #> 158 Run via pls_fit() with big.memory backend
    #> 159                  Requires the pls package
    #> 160             Requires the mixOmics package
    #> 161      Run via pls_fit() with dense backend
    #> 162 Run via pls_fit() with big.memory backend
    #> 163                  Requires the pls package
    #> 164             Requires the mixOmics package
    #> 165      Run via pls_fit() with dense backend
    #> 166 Run via pls_fit() with big.memory backend
    #> 167                  Requires the pls package
    #> 168             Requires the mixOmics package
    #> 173      Run via pls_fit() with dense backend
    #> 174 Run via pls_fit() with big.memory backend
    #> 175                  Requires the pls package
    #> 176             Requires the mixOmics package
    #> 177      Run via pls_fit() with dense backend
    #> 178 Run via pls_fit() with big.memory backend
    #> 179                  Requires the pls package
    #> 180             Requires the mixOmics package
    #> 181      Run via pls_fit() with dense backend
    #> 182 Run via pls_fit() with big.memory backend
    #> 183                  Requires the pls package
    #> 184             Requires the mixOmics package
    #> 189      Run via pls_fit() with dense backend
    #> 190 Run via pls_fit() with big.memory backend
    #> 191                  Requires the pls package
    #> 192             Requires the mixOmics package
    #> 289      Run via pls_fit() with dense backend
    #> 290 Run via pls_fit() with big.memory backend
    #> 291                  Requires the pls package
    #> 292             Requires the mixOmics package
    #> 293      Run via pls_fit() with dense backend
    #> 294 Run via pls_fit() with big.memory backend
    #> 295                  Requires the pls package
    #> 296             Requires the mixOmics package
    #> 301      Run via pls_fit() with dense backend
    #> 302 Run via pls_fit() with big.memory backend
    #> 303                  Requires the pls package
    #> 304             Requires the mixOmics package
    #> 337      Run via pls_fit() with dense backend
    #> 338 Run via pls_fit() with big.memory backend
    #> 339                  Requires the pls package
    #> 340             Requires the mixOmics package
    #> 341      Run via pls_fit() with dense backend
    #> 342 Run via pls_fit() with big.memory backend
    #> 343                  Requires the pls package
    #> 344             Requires the mixOmics package
    #> 349      Run via pls_fit() with dense backend
    #> 350 Run via pls_fit() with big.memory backend
    #> 351                  Requires the pls package
    #> 352             Requires the mixOmics package

The table reports median execution times (in seconds), the number of iterations and memory use per second for a representative single-response scenario. The notes column indicates the additional packages required to reproduce those measurements.

## Takeaways

Dense vs streaming backends. On small/medium data that fits in RAM, in-memory implementations (e.g., pls) are typically fastest (median ≈0.36 s for SIMPLS in our runs). However, they materialize large cross-products/Gram matrices and memory grows as O(p^2) (or O(n^2) in kernel views). In contrast, bigPLSR’s streaming big-memory backend keeps memory bounded via chunked BLAS and never forms those intermediates. In our PLS2 benchmark, streaming used ~7–8× less RAM than pls (≈89 MB vs ≈732 MB median) while remaining competitive in runtime (≈3.5 s vs 0.36 s). PLS1 shows the same pattern: streaming is often fast enough while dramatically reducing memory. As n or p grow, the streaming backend scales where dense approaches become memory-limited.