This package provides a simple timer for Rcpp code. It is similar to the tictoc R package.
The Package wraps cpptimer which is a header only library that contains a class called CppTimer
. ‘rcpptimer’ adds this class as Timer
to the Rcpp
namespace.
With Rcpp::cppFunction
we have to add the depends
argument to the function. To tell the compiler that we want to link the ‘rcpptimer’ library to the ‘Rcpp’ code. That is, we can construct an instance if the Timer
class and use the tic
and toc
methods to measure the time it takes to execute a function. Here, we just allocate some memory to have something to measure:
::cppFunction('
Rcppint mem()
{
Rcpp::Timer timer;
timer.tic("mem");
std::string s;
s.reserve(1048576);
timer.toc("mem");
return(0);
}',
depends = "rcpptimer"
)
mem()
#> [1] 0
print(times)
#> Name Milliseconds SD Count
#> 1 mem 0.003 0 1
The results will be passed to the R environment as a dataframe named times
. If you want to give the dataframe a different name you can pass that name to the constructor:
::cppFunction('
Rcppint mem()
{
Rcpp::Timer timer("mytimes");
timer.tic("mem");
std::string s;
s.reserve(1048576);
timer.toc("mem");
return(0);
}',
depends = "rcpptimer"
)
mem()
#> [1] 0
print(mytimes)
#> Name Milliseconds SD Count
#> 1 mem 0.004 0 1
The default setting will warn about timers that have not been stopped and toc
calls for timers that have not yet been started using a matching call to tic
:
::cppFunction('
Rcppint mem()
{
Rcpp::Timer timer;
timer.tic("start");
std::string s;
timer.tic("reserve");
s.reserve(1048576);
timer.toc("reserve");
timer.toc("finish");
return(0);
}',
depends = "rcpptimer"
)
mem()
#> Warning in mem(): Timer "finish" not started yet.
#> Use tic("finish") to start the timer.
#> Warning in mem(): Timer "start" not stopped yet.
#> Use toc("start") to stop the timer.
#> [1] 0
print(times)
#> Name Milliseconds SD Count
#> 1 reserve 0.004 0 1
Note that this does not affect correctly terminated timers such as reserve
. These warnings occur at runtime. Unfortunately, we can’t check for this at compile time since the tic
and toc
calls might spread over various functions so that (in some cases) we do not know the execution flow upfront.
However, if you are sure that you are using the timer correctly you can disable these warnings by passing false
to the constructor:
::cppFunction('
Rcppint mem()
{
Rcpp::Timer timer(false); // Disable warnings
timer.tic("start");
std::string s;
timer.tic("reserve");
s.reserve(1048576);
timer.toc("reserve");
timer.toc("finish");
return(0);
}',
depends = "rcpptimer"
)
mem()
#> [1] 0
We offer an alternative to the tic-toc interface. The ScopedTimer
lets you measure the time it takes for the object to go out of scope. We can adjust the above example to use the ScopedTimer
instead:
::cppFunction('
Rcppint mem()
{
Rcpp::Timer timer;
Rcpp::Timer::ScopedTimer scoped_timer(timer, "mem");
std::string s;
s.reserve(1048576);
return(0);
}',
depends = "rcpptimer"
)
mem()
#> [1] 0
print(times)
#> Name Milliseconds SD Count
#> 1 mem 0.005 0 1
Note that you only need to initialize the ScopedTimer. Once it goes out of scope it will call timer.toc("mem")
automatically.
We will add vignettes on how to use the package with Rcpp::sourceCpp and how to add it to your package soon.