Adding rcpptimer to a Package
Jonathan Berrisch
2024-09-22
Source:vignettes/packages.Rmd
packages.Rmd
Adding rcpptimer to your Package
Using rcpptimer in your package is simple. Just link to it in your
DESCRIPTION
file:
And add the header into your .cpp file
#include <rcpptimer.h>
. Now, you can create and use
an instance of the Rcpp::Timer
class. Consider this
fibonacci_omp
function:
#include <rcpptimer.h>
long int fib(long int n)
{
return ((n <= 1) ? n : fib(n - 1) + fib(n - 2));
}
//[[Rcpp::export]]
std::vector<long int> fibonacci_omp(std::vector<long int> n)
{
Rcpp::Timer timer;
// This scoped timer measures the total execution time of 'fibonacci'
Rcpp::Timer::ScopedTimer scpdtmr(timer, "fib_body");
std::vector<long int> results = n;
#pragma omp parallel for
for (unsigned int i = 0; i < n.size(); ++i)
{
timer.tic("fib_" + std::to_string(n[i]));
results[i] = fib(n[i]);
timer.toc("fib_" + std::to_string(n[i]));
}
return (results);
}
This function is available in rcpptimer so you can try it yourself,
e.g., rcpptimer::fibonacci(n = rep(20:25, 10))
. After that,
you can inspect the timings by executing print(times)
.
As you can see, it writes the timings to the global environment as
data.frame called times
. Read the following section to
learn why this differs from what you want in a package.
Autoreturn
When using rcpptimer in your package, consider turning off the
timer’s autoreturn
feature. Users of your package may need
to be made aware of this functionality. They may already have an object
named times
in their global environment or may have
rigorous expectations about what objects they want to write into their
environment. Instead, you should include the timings in your data
structures or parameterize the name of the returned object, the
autoreturn
feature itself, or both.
See vignette("autoreturn")
vignette to read about this
in detail.
Reexport Print Method
If you use rcpptimer
in your package, you may want to
suggest rcpptimer
in your DESCRIPTION and register the S3
method print.rcpptimer
. This method is used to print the
timings in a more readable way. It will scale the results to be more
readable. I.e. if all timings are greater than 1 second, it will print
the results in seconds.
Two adjustments are necessary in your package:
First, add the following line to your DESCRIPTION
file:
Second, add the following code to your package:
if (requireNamespace("rcpptimer", quietly = TRUE)) {
registerS3method("print", "rcpptimer", rcpptimer:::print.rcpptimer)
}
This will register print.rcpptimer
if
rcpptimer
is available. You can place this code in a
function that uses rcpptimer
or your package’s
.onLoad
function1.