Fetch from CRAN using:
install.packages("data.table.threads")
or use the latest (developmental) version from here:
if(!require(remotes)) install.packages("remotes"); remotes::install_github("Anirban166/data.table.threads")
if(!require(devtools)) install.packages("devtools"); devtools::install_github("Anirban166/data.table.threads")
findOptimalThreadCount(rowCount, columnCount, ...)
is
the go-to function that runs a set of predefined benchmarks for various
data.table
functions that are parallelizable, across
varying thread counts (iteratively from one to the highest number
available as per the user’s system). It involves computation to find the
optimal/ideal speedup and thread count for each function. It returns a
data.table
object of a custom class (print
and
plot
methods have been provided), which contains the
optimal thread count for each function. It also provides plot data
(consisting of speedup trends and key points) as attributes.
> benchmarks <- data.table.threads::findOptimalThreadCount(1e7, 10, verbose = TRUE)
1 thread, 10000000 rows, and 10 columns.
Running benchmarks with
...10 threads, 10000000 rows, and 10 columns. Running benchmarks with
It returns a data.table
object for which
print
and plot
methods have been provided.
> benchmarks
function Thread count Fastest median runtime (ms)
data.table - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8 99.320183
forder 5 15.709294
GForce_sum 6 57.685606
subsetting 9 23.233573
frollmean 9 7.332542
fcoalesce 8 21.947874
between 5 19.284555
fifelse 6 7.316102
nafill 2 3.658697 CJ
The output here is a table which shows the fastest runtime (median
value in milliseconds) for each applicable data.table
function along with the corresponding thread count that achieved it.
Plotting this object would generate a plot that shows the ideal and measured speedup trends for each routine:
> plot(benchmarkData)
If the user wants to factor in a specified speedup efficiency, they
can use the function addRecommendedEfficiency
to add a
speedup line (with a slope configured by input argument
efficiencyFactor
; default value is 0.5, or 50% efficiency)
along with a point representing the recommended thread count which stems
from the highest intersection between this line (of specified thread-use
efficiency) and measured speedup data for each function:
<- addRecommendedEfficiency(benchmarks, recommendedEfficiency = 0.4)
benchmarks_r plot(benchmarks_r)
In both cases (with our without the addition of recommended efficiency), the generated plot delineates the speedup across multiple threads (from 1 to the number of threads available in the user’s system; 10 in my case here) for each function.
setThreadCount(benchmarks, functionName, efficiencyFactor)
can then be used to set the thread count based on the observed results
for a user-specified function and efficiency value (of the range [0, 1])
for the speedup:
> setThreadCount(benchmarks_r, functionName = "forder", efficiencyFactor = 0.6, verbose = TRUE)
3, based on an efficiency factor of 0.6 for data.table::forder() based on the performed benchmarks.
The number of threads that data.table will use has been set to > getDTthreads()
1] 3 [