[Rcpp-commits] r600 - papers/rjournal
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Feb 6 16:31:22 CET 2010
Author: edd
Date: 2010-02-06 16:31:22 +0100 (Sat, 06 Feb 2010)
New Revision: 600
Modified:
papers/rjournal/EddelbuettelFrancois.tex
Log:
more spit and polish
Modified: papers/rjournal/EddelbuettelFrancois.tex
===================================================================
--- papers/rjournal/EddelbuettelFrancois.tex 2010-02-06 14:48:36 UTC (rev 599)
+++ papers/rjournal/EddelbuettelFrancois.tex 2010-02-06 15:31:22 UTC (rev 600)
@@ -15,27 +15,24 @@
wanting to combine compiled code with R.}
\section{Introduction}
-% [Dirk] I am a tradionalist here ...
-% [Romain] fine. should we then remove the background section
-% and just let its contents be part of 'introduction'
R is an extensible system. The 'Writing R Extensions' manual \citep{R:exts}
-describes in great detail the various ways to augment R with compiled code,
-focussing mostly about C code. The R API described in Writing R Extensions is
+describes in detail the ways to augment R with compiled code,
+focussing mostly on C code. The R API described in Writing R Extensions is
based on a set of functions and macros operating on \code{SEXP}, the internal
representation of R objects.
% appendix A of Chambers's software for data analysis ?
In this article, we discuss the functionality of the \pkg{Rcpp}
package, which we believe simplifies dramatically the usage of C++ code
-in R. Combining R and C++ is not a new idea, so we start by
-a short review of approaches from other authors and give some historical
+in R. Combining R and C++ is not a new idea, so we start with
+a short review of other approaches and give some historical
background on the development of \pkg{Rcpp}.
The current version of \pkg{Rcpp} combines two distincts
-APIs. The first---which we call `classic Rcpp API'---exists since
+APIs. The first---which we call `classic \pkg{Rcpp} API'---exists since
the first version of \pkg{Rcpp}. The second API, enclosed in the
-\code{Rcpp} C++ namespace is a newer codebase, which we started to develop
+\code{Rcpp} C++ namespace is a newer codebase which we started to develop
more recently. This article
% mostly concerns the newer API, and %% [Dirk] Really?
% [Romain] based on relative lengths of coverage ...
@@ -49,7 +46,7 @@
the traditional R API and many more examples are available within
the package.
-\section{Background}
+%\section{Background}
\subsection{Historical Context}
@@ -68,11 +65,11 @@
`classic \pkg{Rcpp}' interface (described in the next section)
which will be maintained for the forseeable future.
-Yet C++ coding standards continued to evolved. So, starting in 2009 the
+Yet C++ coding standards continued to evolve. So starting in 2009 the
codebase was significantly extended and numerous new features were added.
-Several of these are described below in the section on the the `New
+Several of these are described below in the section on the the `new
\pkg{Rcpp}' interface. This new API is our current focus, and we intend to
-both extend and support going forward.
+both extend and support it going forward.
\subsection{Comparison}
@@ -110,7 +107,7 @@
API features, performance, useability and documentation would be a welcome
addition to the literature, but is beyond the scope of this article.
-\section{Classic Rcpp}
+\section{Classic Rcpp API}
\label{sec:classic_rcpp}
The core focus of \pkg{Rcpp}---particularly for the earlier API described in
@@ -123,7 +120,7 @@
This API therefore supports two typical use cases. First, one can think of
replacing existing R code with equivalent C++ code in order to reap
-performance gains. This case can be conceptually easy as there may not be
+performance gains. This case is conceptually easy as there may not be
(built- or run-time) dependencies on other C or C++ libraries. It typically
involves setting up data and parameters---the right-hand side components of a
function call---before making the call in order to provide the result that is
@@ -164,25 +161,25 @@
\code{SEXP} types, a third is returned.
Third, both inputs are converted to templated\footnote{C++ templates
allow functions or classes to be written somewhat independently from the
-template parameter. The actual class is instanciated by the compiler
+template parameter. The actual class is instantiated by the compiler
by replacing occurences of the templated parameter(s).}
C++ vector types, here a standard \code{double}
type is used to create a vector of doubles from the template type.
Fourth, the usefulness of these classes can be seen when we query the
-vectors directly for their size---using the \code{size} member function---in
+vectors directly for their size---using the \code{size()} member function---in
order to reserved a new result type of appropriate length whereas use based
on C arrays would have required additional parameters for the length of
vectors $a$ and $b$, leaving open the possibility of mismatches between the
actual length and the length reported by the programmer.
Fifth, the computation itself is straightforward embedded looping just as in the
original examples in the 'Writing R Extensions' manual \citep{R:exts}.
-Sixth, a return type (\code{RcppResultSet}) is then prepared as a named
+Sixth, a return type (\code{RcppResultSet}) is prepared as a named
object which is then
converted to a list object that is returned. We should note that the
\code{RcppResultSet} permits the return of numerous (named) objects which can
also be of different types.
-We argue that this usage is already easier to read, write and debug than the
+We argue that this usage is already much easier to read, write and debug than the
C macro-based approach supported by R itself. Possible performance issues and
other potential limitations will be discussed throughout the article and
reviewed at the end.
@@ -190,33 +187,30 @@
\section{New \pkg{Rcpp} API}
\label{sec:new_rcpp}
-% [Romain]: removing this pedestrian sentence :
-% Having discussed the `Classic Rcpp' API and its deployment in the previous
-% section, we now turn to the `New Rcpp'.
-In late 2009, the Rcpp API has been dramatically extended, leading to a
+More recently, the \pkg{Rcpp} API has been dramatically extended, leading to a
complete redesign, based on the usage experience of several
years of \pkg{Rcpp} deployment, needs from other projects, knowledge
-of internal R API, as well as current C++ design approaches.
+of the internal R API, as well as current C++ design approaches.
\subsection{Rcpp Class hierarchy}
-The \code{Rcpp::RObject} class is the basic class of the new Rcpp API.
+The \code{Rcpp::RObject} class is the basic class of the new \pkg{Rcpp} API.
An instance of the \code{RObject} class encapsulates an R object
(\code{SEXP}), exposes methods that are appropriate for all types
of objects and transparently manages garbage collection.
The most important aspect of the \code{RObject} class is that it is
-a very thin wrapper around the \code{SEXP} it encapsulates, the
+a very thin wrapper around the \code{SEXP} it encapsulates. The
\code{SEXP} is indeed the only data member of an \code{RObject}. The
\code{RObject} class does not interfere with the way R manages its
memory, does not perform copies of the object into a suboptimal
C++ representation, but instead merely acts as a proxy to the
-object it encapsulates, so that methods applied to the \code{RObject}
+object it encapsulates so that methods applied to the \code{RObject}
instance are relayed back to the \code{SEXP} in terms of the standard
R API.
The \code{RObject} class takes advantage of the explicit life cycle of
-c++ objects to manage exposure of the underlying R object to the
+C++ objects to manage exposure of the underlying R object to the
garbage collector. The \code{RObject} effectively treats
its underlying \code{SEXP} as a resource.
The constructor of the \code{RObject} class takes
@@ -241,7 +235,7 @@
Similarly, the member functions \code{hasSlot} and \code{slot}
can be used to manage slots of an S4 object. These function throw
-c++ exceptions when used on objects that are not S4 objects, or when
+C++ exceptions when used on objects that are not S4 objects, or when
trying to access a slot that does not exist for a class.
\subsection{Derived classes}
@@ -255,17 +249,17 @@
For example \code{Rcpp::Environment} contains
member functions to manage objects in the associated environment.
-Classes related to vectors (\code{IntegerVector}, \code{NumericVector},
+Similarly, classes related to vectors (\code{IntegerVector}, \code{NumericVector},
\code{RawVector}, \code{LogicalVector}, \code{CharacterVector},
\code{GenericVector} and \code{ExpressionVector}) expose functionality
-to extract and set values from the vectors, etc ...
+to extract and set values from the vectors.
-The following sub-sections present typical uses Rcpp classes in
+The following sub-sections present typical uses of \pkg{Rcpp} classes in
comparison with the same code expressed using functions of the R API.
\subsection{Numeric vectors}
-The following code snippet is extracted from Writing R extensions
+The following code snippet is taken from Writing R extensions
\citep{R:exts}. It creates a \code{numeric} vector of two elements
and assigns some values to it.
@@ -278,8 +272,8 @@
\end{example}
Although this is one of the simplest examples in Writing R extensions,
-it seems verbose and it is not trivial at first sight what is happening.
-\code{allocVector} is used to allocate memory; we must also supply it with
+it seems verbose and it is not obvious at first sight what is happening.
+Memory is allocated by \code{allocVector}; we must also supply it with
the type of data (\code{REALSXP}) and the number of elements. Once
allocated, the \code{ab} object must be protected from garbage
collection. Since the garbage collector can happen at any time, not
@@ -304,9 +298,9 @@
the first and second elements of the vector as \code{NumericVector} overloads
the \code{operator[]}.
-With the most recent compilers (e.g. G++ >= 4.4) which already implement
-parts of the forthcoming C++ standard (C++0x), the preceding code may even be
-reduced to this:
+With the most recent compilers (e.g. GNU g++ >= 4.4) which already implement
+parts of the next C++ standard (C++0x) currently being drafted, the preceding
+code may even be reduced to this:
\begin{example}
Rcpp::NumericVector ab = \{123.45, 67.89\};
@@ -349,11 +343,12 @@
\subsection{C++ to R : wrap}
-The C++ to R conversion is performed by the \code{Rcpp::wrap} templated
-function. It uses advanced template meta programming techniques
-to convert a wide and extensible set of types and classes to the
-most appropriate type of R object. The signature of the \code{wrap}
-template is:
+The C++ to R conversion is performed by the \code{Rcpp::wrap} templated
+function. It uses advanced template meta programming techniques\footnote{A
+ discussion of template meta programming is beyond the scope of this
+ article.} to convert a wide and extensible set of types and classes to the
+most appropriate type of R object. The signature of the \code{wrap} template
+is:
\begin{example}
template <typename T>
@@ -361,15 +356,15 @@
\end{example}
The templated function takes a reference to a `wrappable`
-object and convert this object into a \code{SEXP}, which is what R expects.
+object and converts this object into a \code{SEXP}, which is what R expects.
Currently wrappable types are :
\begin{itemize}
\item primitive types, \code{int}, \code{double}, ... which are converted
into atomic R vectors of the appropriate type;
-\item \code{std::string} are converted to R atomic character vectors;
-\item STL-like containers such as \code{std::vector<T>} or \code{std::list<T>},
+\item \code{std::string} which are converted to R atomic character vectors;
+\item STL containers such as \code{std::vector<T>} or \code{std::list<T>},
as long as the template parameter type \code{T} is itself wrappable;
-\item STL-like maps which uses \code{std::string} for keys
+\item STL maps which use \code{std::string} for keys
(e.g. \code{std::map<std::string,T>}); as long as
the type \code{T} is wrappable;
\item any type that implements implicit conversion to \code{SEXP} through the
@@ -377,19 +372,19 @@
\item any type for which the the \code{wrap} template is partially or fully
specialized.
% [Romain]: should we mention RInside as an example
+% [Dirk] Example for _what_ ?
\end{itemize}
Whether an object is wrappable is resolved at compile time, and the
dispatch of the appropriate implementation is performed by the compiler
using modern techniques of template meta programming and class traits.
-
The design allows composition, so for example objects of the class
\code{std::vector< std::map<std::string,int> >} are wrappable. This is
because \code{int} is wrappable (as a primitive type), consequently
-\code{std::map<std::string,int>} is wrappable (as an STL-like map of
+\code{std::map<std::string,int>} is wrappable (as an STL map of
wrappable types keyed by strings, and therefore
\code{std::vector< std::map<std::string,int> >} is wrappable (as a
-STL-like container of wrappable objects). The example code below
+STL container of wrappable objects). The example code below
illustrates this:
\begin{example}
@@ -411,21 +406,20 @@
can be created by the following R code.
\begin{example}
-list(
- c( bar = 2L, foo = 1L) ,
- c( bar = 2L, bling = 3L, foo = 1L) )
+list( c( bar = 2L, foo = 1L) ,
+ c( bar = 2L, bling = 3L, foo = 1L) )
\end{example}
\subsection{R to C++ : as}
The reversed conversion is implemented by variations of the
-\code{Rcpp::as} template. \code{as} offers less flexibility and currently
+\code{Rcpp::as} template. It offers less flexibility and currently
handles conversion of R objects into primitive types (bool, int, std::string, ...),
STL vectors of primitive types (\code{std::vector<bool>},
\code{std::vector<double>}, etc ...) and arbitrary types that offer
a constructor that takes a \code{SEXP}. In addition \code{as} can
be fully or partially specialized to manage conversion of R data
-structures to third party types.
+structures to third-party types.
\subsection{Implicit use of converters}
@@ -442,7 +436,7 @@
# assuming the global environment contains
# a variable 'x' that is a numeric vector
Rcpp::Environment global =
- Rcpp::Environment::global_env()
+\ \ \ \ Rcpp::Environment::global_env()
# extract a std::vector<double> from
# the global environment
@@ -461,17 +455,17 @@
\code{std::vector<double>} from the global environment. This is
achieved by the templated \code{operator[]} of \code{Environment}
that first extracts the requested object from the environment as a \code{SEXP},
-and then outsource to \code{Rcpp::as} the creation of the
+and then outsources to \code{Rcpp::as} the creation of the
requested type.
-In the second part of the example, the \code{operator[]} this time
-first delegates to wrap the production of an R object based on the
+In the second part of the example, the \code{operator[]}
+delegates to wrap the production of an R object based on the
type that is passed in (\code{std::map<std::string,std::string>}),
-and then assign the object to the requested name.
+and then assigns the object to the requested name.
-The same mechanism is used throughout the API, including : access/modification
+The same mechanism is used throughout the API. Examples include access/modification
of object attributes, slots, elements of generic vectors (lists),
-function arguments, nodes of dotted pair lists and language calls, etc ...
+function arguments, nodes of dotted pair lists and language calls and more.
\section{Function calls}
@@ -483,13 +477,14 @@
The code can be expressed in several ways in \pkg{Rcpp}, the first version
shows the use of the \code{Environment} and \code{Function} classes
-\footnote{We have removed the \code{Rcpp::} prefix from the
-following examples for readability.}.
+\footnote{We have removed the \code{Rcpp::} prefix from the following
+ examples for readability; this corresponds to adding a statement
+ \texttt{using namespace Rcpp;} in the code}.
\begin{example}
-Environment stats("package:stats") ;
-Function rnorm = stats.get("rnorm") ;
-return rnorm(10, Named("sd", 100.0) ) ;
+Environment stats("package:stats");
+Function rnorm = stats.get("rnorm");
+return rnorm(10, Named("sd", 100.0) );
\end{example}
We first pull out the \code{rnorm} function from the environment
@@ -501,32 +496,32 @@
manage calls (LANGSXP).
\begin{example}
-Language call("rnorm", 10, Named("sd", 100 ) ) ;
-call.eval() ;
+Language call("rnorm", 10, Named("sd", 100 ));
+call.eval();
\end{example}
In this version, we first create a call to the symbol "rnorm" and
evaluate the call in the global environment. In both cases, \code{wrap}
is used implicitely to convert \code{10} and \code{100}
into R integer vectors. It should be noted that this
-version involves potentially expensive implicit lookup in the search path
-to find the "rnorm" function.
+version involves a potentially expensive implicit lookup in the search path
+to find the \code{rnorm} function.
% should we quote luke's : http://www.cs.uiowa.edu/~luke/R/bytecode.html
-Using the R API, the first example, using the actual \code{rnorm} function,
+For comparison, using the standard R API, the first example using the actual \code{rnorm} function
translates to :
\begin{example}
SEXP stats = PROTECT(
-\ \ R_FindNamespace( mkString("stats") ) ) ;
+\ \ R_FindNamespace( mkString("stats") ) );
SEXP rnorm = PROTECT(
-\ \ findVarInFrame( stats, install("rnorm") ) ) ;
+\ \ findVarInFrame( stats, install("rnorm") ) );
SEXP call = PROTECT(
\ \ LCONS( rnorm,
\ \ \ \ CONS(ScalarInteger(10),
-\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue)))) ;
-SET_TAG( CDDR(call), install("sd") ) ;
-SEXP res = PROTECT( eval( call, R_GlobalEnv ) );
+\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
+SET_TAG( CDDR(call), install("sd") );
+SEXP res = PROTECT( eval( call, R_GlobalEnv));
UNPROTECT(4) ;
return res ;
\end{example}
@@ -537,22 +532,24 @@
SEXP call = PROTECT(
\ \ LCONS( install("rnorm"),
\ \ \ \ CONS(ScalarInteger(10),
-\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue)))) ;
+\ \ \ \ \ \ CONS(ScalarReal(100.0), R_NilValue))));
SET_TAG( CDDR(call), install("sd") ) ;
-SEXP res = PROTECT( eval( call, R_GlobalEnv ) );
+SEXP res = PROTECT( eval( call, R_GlobalEnv));
UNPROTECT(2) ;
return res ;
\end{example}
-More examples are available as part of the documentation
-included in \pkg{Rcpp} as well as its unit tests.
+showing that the \pkg{Rcpp} API permits us to work with code that is easier
+to read, write and maintain. More examples are available as part of the documentation
+included in the \pkg{Rcpp} package, as well as among its over one hundred and
+fifty unit tests.
\section{Using code `inline'}
\label{sec:inline}
Extending R with compiled code also needs to address how to reliably compile,
link and load the code. While using a package is preferable in the long run,
-it may be to heavy a framework for quick explorations. An alternative is
+it may be too heavy a framework for quick explorations. An alternative is
provided by the \pkg{inline} package \citep{cran:inline} which compiles,
links and loads a C, C++ or Fortran function---directly from the R prompt
using a simple function \code{cfunction}. It was recently extended to work
@@ -566,34 +563,41 @@
\code{install.packages()} function for initial installation as well as
\code{update.packages()} for upgrades. So even though R / C++ interfacing
would otherwise require source code, the \pkg{Rcpp} library is always provided
-ready for use as a pre-built library through the CRAN package mechanism.
+ready for use as a pre-built library through the CRAN package
+mechanism.\footnote{This presumes a platform for which prebuild binaries a
+ provided. \pkg{Rcpp} is available in binary form for Windows and OS X users from
+ CRAN, and a \code{.deb} package for Debian and Ubuntu users. For other systems, the
+ \pkg{Rcpp} library is automatically built from source during installation
+ or upgrades.}
The library and header files provided by \pkg{Rcpp} for use by other packages
are installed along with the \pkg{Rcpp} package making it possible for
\pkg{Rcpp} to provide the appropriate \code{-I} and \code{-L} switches needed
for compilation and linking. So internally, \pkg{inline} makes uses of the
two functions \code{Rcpp:::CxxFlags()} and \code{Rcpp:::LdFlags()} that
-provide this information (and which are also used by \code{Makefiles} of
+provide this information (and which are also used by \code{Makevars} files of
other packages). Here, however, all this is done behind the scenes and the
user need not worry about compiler or linker options or settings.
-The convolution example provided above now can be rewritten for use by
-\pkg{inline} as shown here. The function body is provided by character
+The convolution example provided above can be rewritten for use by
+\pkg{inline} as shown below. The function body is provided by the character
variable \code{src}, the function header is defined by the argument
\code{signature}---and we only need to enable \code{Rcpp=TRUE} to obtain a
new function \code{fun} based on the C++ code in \code{src} where we also
-switched from the classic Rcpp API to the new one:
+switched from the classic \pkg{Rcpp} API to the new one:
\begin{example}
src <- '
Rcpp::NumericVector xa(a);
Rcpp::NumericVector xb(b);
int n_xa = xa.size(), n_xb = xb.size();
- int nab = n_xa + n_xb - 1;
- Rcpp::NumericVector xab(nab);
+
+ Rcpp::NumericVector xab(n_xa + n_xb - 1);
+
for (int i = 0; i < n_xa; i++)
for (int j = 0; j < n_xb; j++)
xab[i + j] += xa[i] * xb[j];
+
return xab;
'
fun <- cfunction(
@@ -611,7 +615,7 @@
\section{Error handling}
Code that uses both R and C++ has to deal with two concurrent
-error handling models. \pkg{Rcpp} simplifies this and allow both
+error handling models. \pkg{Rcpp} simplifies this and allows both
systems to work together.
\subsection{C++ exceptions in R}
@@ -621,9 +625,9 @@
convert this exception to an R error.
In C++, when an application throws an exception that is not caught,
-a special function is invoked, the terminate handler, typically causing
+a special function (called the terminate handler) is invoked. This typically causes
the program to abort. \pkg{Rcpp} takes advantage of this mechanism
-and sets its own terminate handler which translates the c++
+and sets its own terminate handler which translates the C++
exception into an R condition and throws this condition so that it can
be caught in R. The following code gives an illustration.
@@ -646,41 +650,43 @@
\subsection{R error in C++}
R currently does not offer C-level mechanisms to deal with errors. To
-deal with this problem, \pkg{Rcpp} uses the \code{Rcpp::Evaluator}
+overcome this problem, \pkg{Rcpp} uses the \code{Rcpp::Evaluator}
class to evaluate en expression with an R-level \code{tryCatch}
block. The error, if any, that occurs while evaluating the
-function is then translated in terms of C++ exception.
+function is then translated in terms of an C++ exception.
% example ?
+% [Dirk] We're running out of space. In the JSS piece...
-\section{Performance/Limitations}
+\section{Performance and Limitations}
-In this section, we illustrate that C++ features come with a price
-in terms of performance. As users of \pkg{Rcpp}, we do not want
-to replace performance with comfort.
+In this section, we illustrate how C++ features may well come with a price
+in terms of performance. However, as users of \pkg{Rcpp}, we do not need to
+substitute performance with ease of use.
As part of the redesign of \pkg{Rcpp}, data copy is kept to the
-absolute minimum, the \code{RObject} class and all its derived
-classes are just a container for a \code{SEXP}, we let R perform
+absolute minimum. The \code{RObject} class and all its derived
+classes are just a container for a \code{SEXP}. We let R perform
all memory management and access data though the macros or functions
-offered by the standard R API. In contrasts, some data structures
+offered by the standard R API. In contrast, some data structures
of the classic \pkg{Rcpp} interface such as the templated
\code{RcppVector} used containers offered by the standard template
-library to hold the data, requiring copy of the data
+library to hold the data, requiring explicit copies of the data
from R to C++ and back.
In this section, we illustrate how to take advantage of \code{Rcpp} to get
-the best of it. The classic Rcpp translation of the convolve example from
-\cite{R:exts} appears in sections~\ref{sec:classic_rcpp} and
-\ref{sec:inline} where the latter example showed the use with the new API.
+the best of both worlds. The classic \pkg{Rcpp} translation of the convolve example from
+\cite{R:exts} appears twice above where the second example showed the use
+with the new API.
+% [Dirk] Seemingly, no \ref with the RJournal style
-The implementation of the \code{operator[]} is implemented as
-efficiently as possible, using inlining and caching,
-but this implementation is still less efficient than the
+The implementation of the \code{operator[]} is designed as
+efficiently as possible, using both inlining and caching,
+but even this implementation is still less efficient than the
reference C imlementation described in \cite{R:exts}.
In order to achieve maximum efficiency, the reference implementation
-extracts the underlying array pointer : \code{double*} and works
+extracts the underlying array pointer \code{double*} and works
with pointer arithmetics, which is a built-in operation as opposed to
calling the \code{operator[]} on a user-defined class which has to
pay the price of object encapsulation.
@@ -699,8 +705,7 @@
Rcpp::NumericVector xb(b);
int n_xa = xa.size() ;
int n_xb = xb.size() ;
- int nab = n_xa + n_xb - 1;
- Rcpp::NumericVector xab(nab);
+ Rcpp::NumericVector xab(n_xa + n_xb - 1);
double* pa = xa.begin() ;
double* pb = xb.begin() ;
@@ -714,9 +719,9 @@
\}
\end{example}
-We've benchmarked the various implementations using
+We have benchmarked the various implementations using
1000 replicates of each function with \code{a} and
-\code{b} containing 100 elements. The timings are summarized in the
+\code{b} containing 100 elements each. The timings are summarized in the
table below:
\begin{center}
@@ -745,35 +750,35 @@
and calling an overloaded \code{operator[]} as opposed to using
pointer arithmetics.
-Finally the second implementation --- from the classic Rcpp API ---
-is clearly behind in terms of efficiency. The difference is mainly
+Finally the second implementation---from the classic \pkg{Rcpp} API---is
+clearly behind in terms of efficiency. The difference is mainly
caused by the many unnecessary copies that the \code{RcppVector<double>}
class performs. First, both objects (\code{a} and \code{b})
are copied into C++ structures (\code{xa} and \code{xb}).
Then, the result is constructed as another \code{RcppVector<double>}
(\code{xab}) that is filled using the \code{operator()} which checks
-every time that the index are suitable for the object. Finally, \code{xab}
+at each access that the index is suitable for the object. Finally, \code{xab}
is converted back to an R object.
\section{Summary}
-The \code{Rcpp} package simplifies integration of compiled code
+The \code{Rcpp} package greatly simplifies integration of compiled C++ code
with R.
The class hierarchy allows manipulation of R data structures in C++
using member functions and operators directly related to the type
of object being used, therefore reducing the level of expertise
required to master the various functions and macros offered by the
-traditional R internal API. The classes assume the entire
+internal R API. The classes assume the entire
responsability of garbage collection of objects, relieving the
programmer from book-keeping operations with the protection stack
-and enabling him/her to focus on the scientific problem.
+and enabling him/her to focus on the underlying problem.
-Data interchange between R and C++ --- performed by the
-\code{wrap} and \code{as} template functions --- allow the programmer
-to write logic in terms of c++ data structures, facilitating use
+Data interchange between R and C++---performed by the
+\code{wrap} and \code{as} template functions---allow the programmer
+to write logic in terms of C++ data structures, facilitating use
of modern libraries such as the standard template library and its
-containers and algorithms. \code{wrap} and \code{as} are extensible
+containers and algorithms. The \code{wrap} and \code{as} functions are extensible
by design and can be used either explicitely or implicitely throughout
the API.
@@ -781,12 +786,13 @@
the footprint of the \code{Rcpp} API is very lightweight, and does not
induces a significant performance price.
-Using the \code{Rcpp} api dramatically reduces the complexity
+Using the \code{Rcpp} API dramatically reduces the complexity
of the code, which improves code readability and maintainability.
The redesign of \code{Rcpp} was motivated by the needs of other
-projects such as \code{RInside} for easy embedding
-of R in a c++ application and \code{RProtoBuf} \citep{cran:rprotobuf}
+projects such as \code{RInside} \citep{cran:rinside} for easy embedding
+of R in a C++ application and \code{RProtoBuf} \citep{cran:rprotobuf}
that interfaces with the protocol buffer library.
+% [Dirk] Do we really need to cite RInside and RProtoBuf?
\bibliography{EddelbuettelFrancois}
More information about the Rcpp-commits
mailing list