Skip to content

Commit

Permalink
version 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
BerriJ authored and cran-robot committed Mar 21, 2024
1 parent cbd2bf6 commit 67cabf3
Show file tree
Hide file tree
Showing 13 changed files with 1,087 additions and 35 deletions.
11 changes: 6 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: rcpptimer
Type: Package
Title: 'Rcpp' Tic-Toc Timer with 'OpenMP' Support
Version: 1.0.0
Date: 2024-02-29
Version: 1.1.0
Date: 2024-03-20
Authors@R: c(
person(given = "Jonathan",
family = "Berrisch",
Expand All @@ -16,12 +16,13 @@ Encoding: UTF-8
Imports: Rcpp
LinkingTo: Rcpp
RoxygenNote: 7.3.1
Suggests: testthat (>= 3.0.0)
Suggests: testthat (>= 3.0.0), knitr, rmarkdown
Config/testthat/edition: 3
VignetteBuilder: knitr
Language: en-US
NeedsCompilation: yes
Packaged: 2024-03-01 20:00:04 UTC; vscode
Packaged: 2024-03-20 09:00:22 UTC; vscode
Author: Jonathan Berrisch [aut, cre] (<https://orcid.org/0000-0002-4944-9074>)
Maintainer: Jonathan Berrisch <Jonathan@Berrisch.biz>
Repository: CRAN
Date/Publication: 2024-03-05 10:40:06 UTC
Date/Publication: 2024-03-20 09:20:03 UTC
18 changes: 12 additions & 6 deletions MD5
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
faadeca883cf56b7ff67ffeebc23a481 *DESCRIPTION
906962a4d1ca5c1ebf0f85a19ce86a6e *DESCRIPTION
4aabfcbf4e92208542829bf4a45e35e8 *NAMESPACE
1de59792b871d8882d4c4fc6f17bc02f *NEWS.md
6b15d7ce9de5940bee950c049412a51e *NEWS.md
9d01228e1641aa7ebc5f2df4c3c1dbb0 *R/RcppExports.R
11e706f16d1b0fb731d81f601a64ada0 *R/package.R
7b21a0d9234e44a9e6f3ef4c44f685d5 *README.md
afb8e402ac5aade16479ef7fa3a3c475 *README.md
43d5ee5aba7428ef481c19a6ae682df5 *build/vignette.rds
556c64456aeaf4b12a1ba599b96c89a9 *inst/doc/rcpptimer.R
d8cc82280e1009559336e25e38f9e6d1 *inst/doc/rcpptimer.Rmd
1fb88eb7ddedb9876e139585497e26ae *inst/doc/rcpptimer.html
aaeae129dceaab27b119cf46aaf0783b *inst/include/chameleon.h
1ebbd3e34237af26da5dc08a4e440464 *inst/include/cpptimer/LICENSE
69cbb9e2f794d1bb44a5d6e2e0950257 *inst/include/cpptimer/README.md
cdf9c2e54a4e914fc11ec1c0ff2ca818 *inst/include/cpptimer/cpptimer.h
cf9438d029787dce91ce358a527a7363 *inst/include/rcpptimer.h
f7fd8c8432743c613979417f67c2c958 *inst/include/cpptimer/cpptimer.h
59702d12b64f7f59b5c2e5b42fd4febe *inst/include/rcpptimer.h
c8d6802f3df1d9760f2b15c6c9c8daaf *man/fibonacci.Rd
cf65a98fcf724a50385ac378116e9dbe *man/fibonacci_omp.Rd
ce2c3134cfc6f3f344e98ad6d5022d2f *src/Makevars
657ceb64c962dd262d085de9668f8d96 *src/Makevars.win
611eecf22c6f401e51563dfe193c2937 *src/RcppExports.cpp
a40d192f45e09c4c24ed4c1fae5dea67 *src/fibonacci.cpp
55e3f1b4d00db11ce3513b4358120883 *src/fibonacci.cpp
f3bd93b3a3c8ae369ab2c835fd29d796 *tests/testthat.R
aae583fe9843ab060a90875a08aba5d7 *tests/testthat/test_rcppclock.R
d8cc82280e1009559336e25e38f9e6d1 *vignettes/rcpptimer.Rmd
31 changes: 25 additions & 6 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
rcpptimer 1.1.0
==============

## Improvements

* Add new `Rcpp::CppTimer::ScopedTimer` class. This can be used to time the lifespan of an object until it goes out of scope. This is useful for timing the duration of a function or a loop. The `fibonacci` example was updated to use this new class.
* Warn about timers that are not stopped when aggregate is called (no matching `toc()` statement).
* Warn about timers for which no matching `tic()` statement was found.
* Add `verbose` parameter to the `Timer` class to control whether above warnings should be printed or not (defaults to `true`).
* Add introductory vignette to the package.

## Fixes

* Fixed cases where only `toc()` was called without matching `tic()`.
* This led to a segfault in the previous version.
* Fix `reset()` method which was not working properly in some cases where timers spread out over multiple methods.
* Fix non-default constructors of the `Timer` class. They were not working properly in the previous version.

rcpptimer 1.0.0
==============

This is the initial release of `rcpptimer`. It is based on `RcppClock` but contains a number of improvements:
- OpenMP support
- Auomatically returns results to R as soon as the C++ Object goes out of scope
- Fast computation of Mean and Standard Deviation of the results in C++
- Uses `tic` and `toc` instead of `tick` and `tock` to be consistent with R's `tictoc` package
- Allways reports microseconds resolution
- Many more performance improvements

* OpenMP support
* Auomatically returns results to R as soon as the C++ Object goes out of scope
* Fast computation of Mean and Standard Deviation of the results in C++
* Uses `tic` and `toc` instead of `tick` and `tock` to be consistent with R's `tictoc` package
* Allways reports microseconds resolution
* Many more performance improvements
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,34 @@ Nothing has to be changed with respect to your `timer` instance. The timings sho
5 fib_body 908.919 0.000 1
```

## Scoped Timer

We also added a new `Rcpp::CppTimer::ScopedTimer`. This can be used to time the lifespan of an object until it goes out of scope. This is useful for timing the duration of a function or a loop. Below is the `fibonacci` example from above. However, we replace the "fib_body" tic-toc timer with the scoped version.

```c++
std::vector<int> fibonacci(std::vector<int> n)
{
Rcpp::Timer timer;

// This scoped timer measures the total execution time of 'fibonacci'
Rcpp::Timer::ScopedTimer scpdtmr(timer, "fib_body");

std::vector<int> results = n;

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);
}
```
Note that you can name your object (in this example `scpdtmr`) however you like. `Rcpp::CppTimer::ScopedTimer` acts as a wrapper, so it will call `.tic` upon construction and `.toc` will be called automatically upon destruction.
`Rcpp::CppTimer::ScopedTimer` is useful to time the duration of a function or a loop.
## Limitations
Processes taking less than a microsecond cannot be timed.
Expand Down
Binary file added build/vignette.rds
Binary file not shown.
101 changes: 101 additions & 0 deletions inst/doc/rcpptimer.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
collapse = TRUE,
# dev = "svg",
warning = TRUE,
message = FALSE,
comment = "#>"
)
Sys.setenv("OMP_THREAD_LIMIT" = 2)

## ----eval = TRUE--------------------------------------------------------------
Rcpp::cppFunction('
int mem()
{
Rcpp::Timer timer;
timer.tic("mem");
std::string s;
s.reserve(1048576);
timer.toc("mem");
return(0);
}',
depends = "rcpptimer"
)

mem()

print(times)

## ----eval = TRUE--------------------------------------------------------------
Rcpp::cppFunction('
int mem()
{
Rcpp::Timer timer("mytimes");
timer.tic("mem");
std::string s;
s.reserve(1048576);
timer.toc("mem");
return(0);
}',
depends = "rcpptimer"
)

mem()

print(mytimes)

## ----eval = TRUE--------------------------------------------------------------
Rcpp::cppFunction('
int 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()

print(times)

## ----eval = TRUE--------------------------------------------------------------
Rcpp::cppFunction('
int 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()

## ----eval = TRUE--------------------------------------------------------------
Rcpp::cppFunction('
int mem()
{
Rcpp::Timer timer;
Rcpp::Timer::ScopedTimer scoped_timer(timer, "mem");
std::string s;
s.reserve(1048576);
return(0);
}',
depends = "rcpptimer"
)

mem()

print(times)

148 changes: 148 additions & 0 deletions inst/doc/rcpptimer.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
title: "Introduction"
author: Jonathan Berrisch
date: "`r Sys.Date()`"
output:
rmarkdown::html_vignette:
number_sections: no
toc: no
vignette: >
%\VignetteIndexEntry{Introduction}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
# dev = "svg",
warning = TRUE,
message = FALSE,
comment = "#>"
)
Sys.setenv("OMP_THREAD_LIMIT" = 2)
```

# A Short Introduction to rcpptimer

This package provides a simple timer for Rcpp code. It is similar to the [tictoc](https://CRAN.R-project.org/package=tictoc) R package.

The Package wraps [cpptimer](https://github.com/BerriJ/cpptimer) which is a header only library that contains a class called `CppTimer`. 'rcpptimer' adds this class as `Timer` to the `Rcpp` namespace.

## Basic usage of the Timer with Rcpp::cppFunction

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:

```{r, eval = TRUE}
Rcpp::cppFunction('
int mem()
{
Rcpp::Timer timer;
timer.tic("mem");
std::string s;
s.reserve(1048576);
timer.toc("mem");
return(0);
}',
depends = "rcpptimer"
)
mem()
print(times)
```

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:

```{r, eval = TRUE}
Rcpp::cppFunction('
int mem()
{
Rcpp::Timer timer("mytimes");
timer.tic("mem");
std::string s;
s.reserve(1048576);
timer.toc("mem");
return(0);
}',
depends = "rcpptimer"
)
mem()
print(mytimes)
```

## Warnings and how to disable them

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`:

```{r, eval = TRUE}
Rcpp::cppFunction('
int 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()
print(times)
```

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:

```{r, eval = TRUE}
Rcpp::cppFunction('
int 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()
```

## Rcpp::Timer::ScopedTimer

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:

```{r, eval = TRUE}
Rcpp::cppFunction('
int mem()
{
Rcpp::Timer timer;
Rcpp::Timer::ScopedTimer scoped_timer(timer, "mem");
std::string s;
s.reserve(1048576);
return(0);
}',
depends = "rcpptimer"
)
mem()
print(times)
```

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.

0 comments on commit 67cabf3

Please sign in to comment.