Dirk Eddelbuettel
2015-Mar-02 14:43 UTC
[Rd] R-devel does not update the C++ returned variables
On 2 March 2015 at 09:09, Duncan Murdoch wrote:
| I generally recommend that people use Rcpp, which hides a lot of the
| details. It will generate your .Call calls for you, and generate the
| C++ code that receives them; you just need to think about the real
| problem, not the interface. It has its own learning curve, but I think
| it is easier than using the low-level code that you need to work with .Call.
Thanks for that vote, and I second that.
And these days the learning is a lot flatter than it was a decade ago:
R> Rcpp::cppFunction("NumericVector doubleThis(NumericVector x) {
return(2*x); }")
R> doubleThis(c(1,2,3,21,-4))
[1] 2 4 6 42 -8
R>
That defined, compiled, loaded and run/illustrated a simple function.
Dirk
--
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Martin Maechler
2015-Mar-02 15:37 UTC
[Rd] R-devel does not update the C++ returned variables
> On 2 March 2015 at 09:09, Duncan Murdoch wrote: > | I generally recommend that people use Rcpp, which hides a lot of the > | details. It will generate your .Call calls for you, and generate the > | C++ code that receives them; you just need to think about the real > | problem, not the interface. It has its own learning curve, but I think > | it is easier than using the low-level code that you need to work with .Call.> Thanks for that vote, and I second that.> And these days the learning is a lot flatter than it was a decade ago:> R> Rcpp::cppFunction("NumericVector doubleThis(NumericVector x) { return(2*x); }") > R> doubleThis(c(1,2,3,21,-4)) > [1] 2 4 6 42 -8 > R>> That defined, compiled, loaded and run/illustrated a simple function.> DirkIndeed impressive, ... and it also works with integer vectors something also not 100% trivial when working with compiled code. When testing that, I've went a step further: ##---- now "test": require(microbenchmark) i <- 1:10 (mb <- microbenchmark(doubleThis(i), i*2, 2*i, i*2L, 2L*i, i+i, times=2^12)) ## Lynne (i7; FC 20), R Under development ... (2015-03-02 r67924): ## Unit: nanoseconds ## expr min lq mean median uq max neval cld ## doubleThis(i) 762 985 1319.5974 1124 1338 17831 4096 b ## i * 2 124 151 258.4419 164 221 22224 4096 a ## 2 * i 127 154 266.4707 169 216 20213 4096 a ## i * 2L 143 164 250.6057 181 234 16863 4096 a ## 2L * i 144 177 269.5015 193 237 16119 4096 a ## i + i 152 183 272.6179 199 243 10434 4096 a plot(mb, log="y", notch=TRUE) ## hmm, looks like even the simple arithm. differ slightly ... ## ## ==> zoom in: plot(mb, log="y", notch=TRUE, ylim = c(150,300)) dev.copy(png, file="mbenchm-doubling.png") dev.off() # [ <- why do I need this here for png ??? ] ##--> see the appended *png graphic Those who've learnt EDA or otherwise about boxplot notches, will know that they provide somewhat informal but robust pairwise tests on approximate 5% level.>From these, one *could* - possibly wrongly - conclude that'i * 2' is significantly faster than both 'i * 2L' and also 'i + i' ---- which I find astonishing, given that i is integer here... Probably no reason for deep thoughts here, but if someone is enticed, this maybe slightly interesting to read. Martin Maechler, ETH Zurich -------------- next part -------------- A non-text attachment was scrubbed... Name: mbenchm-doubling.png Type: image/png Size: 7244 bytes Desc: not available URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20150302/0f61efab/attachment.png>
Dirk Eddelbuettel
2015-Mar-02 19:39 UTC
[Rd] R-devel does not update the C++ returned variables
On 2 March 2015 at 16:37, Martin Maechler wrote:
|
| > On 2 March 2015 at 09:09, Duncan Murdoch wrote:
| > | I generally recommend that people use Rcpp, which hides a lot of the
| > | details. It will generate your .Call calls for you, and generate the
| > | C++ code that receives them; you just need to think about the real
| > | problem, not the interface. It has its own learning curve, but I think
| > | it is easier than using the low-level code that you need to work with
.Call.
|
| > Thanks for that vote, and I second that.
|
| > And these days the learning is a lot flatter than it was a decade ago:
|
| > R> Rcpp::cppFunction("NumericVector doubleThis(NumericVector x) {
return(2*x); }")
| > R> doubleThis(c(1,2,3,21,-4))
| > [1] 2 4 6 42 -8
| > R>
|
| > That defined, compiled, loaded and run/illustrated a simple function.
|
| > Dirk
|
| Indeed impressive, ... and it also works with integer vectors
| something also not 100% trivial when working with compiled code.
|
| When testing that, I've went a step further:
As you may know, int can be 'casted up' to double which is what happens
here. So in what follows you _always_ create a copy from an int vector to a
numeric vector.
For pure int, use eg
Rcpp::cppFunction("IntegerVector doubleThis(IntegeerVector x) {
return(2*x); }")
and rename the function names as needed to have two defined concurrently.
Dirk
|
| ##---- now "test":
| require(microbenchmark)
| i <- 1:10
| (mb <- microbenchmark(doubleThis(i), i*2, 2*i, i*2L, 2L*i, i+i,
times=2^12))
| ## Lynne (i7; FC 20), R Under development ... (2015-03-02 r67924):
| ## Unit: nanoseconds
| ## expr min lq mean median uq max neval cld
| ## doubleThis(i) 762 985 1319.5974 1124 1338 17831 4096 b
| ## i * 2 124 151 258.4419 164 221 22224 4096 a
| ## 2 * i 127 154 266.4707 169 216 20213 4096 a
| ## i * 2L 143 164 250.6057 181 234 16863 4096 a
| ## 2L * i 144 177 269.5015 193 237 16119 4096 a
| ## i + i 152 183 272.6179 199 243 10434 4096 a
|
| plot(mb, log="y", notch=TRUE)
| ## hmm, looks like even the simple arithm. differ slightly ...
| ##
| ## ==> zoom in:
| plot(mb, log="y", notch=TRUE, ylim = c(150,300))
|
| dev.copy(png, file="mbenchm-doubling.png")
| dev.off() # [ <- why do I need this here for png ??? ]
| ##--> see the appended *png graphic
|
| Those who've learnt EDA or otherwise about boxplot notches, will
| know that they provide somewhat informal but robust pairwise tests on
| approximate 5% level.
| >From these, one *could* - possibly wrongly - conclude that
| 'i * 2' is significantly faster than both 'i * 2L' and also
| 'i + i' ---- which I find astonishing, given that i is integer
here...
|
| Probably no reason for deep thoughts here, but if someone is
| enticed, this maybe slightly interesting to read.
|
| Martin Maechler, ETH Zurich
|
| [DELETED ATTACHMENT mbenchm-doubling.png, PNG image]
--
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
On 03/02/2015 04:37 PM, Martin Maechler wrote:> >> On 2 March 2015 at 09:09, Duncan Murdoch wrote: >> | I generally recommend that people use Rcpp, which hides a lot of the >> | details. It will generate your .Call calls for you, and generate the >> | C++ code that receives them; you just need to think about the real >> | problem, not the interface. It has its own learning curve, but I think >> | it is easier than using the low-level code that you need to work with .Call. > >> Thanks for that vote, and I second that. > >> And these days the learning is a lot flatter than it was a decade ago: > >> R> Rcpp::cppFunction("NumericVector doubleThis(NumericVector x) { return(2*x); }") >> R> doubleThis(c(1,2,3,21,-4)) >> [1] 2 4 6 42 -8 >> R> > >> That defined, compiled, loaded and run/illustrated a simple function. > >> Dirk > > Indeed impressive, ... and it also works with integer vectors > something also not 100% trivial when working with compiled code. > > When testing that, I've went a step further: > > ##---- now "test": > require(microbenchmark) > i <- 1:10Note that the relative speed of the algorithms also depends on the size of the input vector. i + i becomes the winner for longer vectors (e.g. i <- 1:1e6), but a proper Rcpp version is still approximately twice as fast. Rcpp::cppFunction("NumericVector doubleThisNum(NumericVector x) { return(2*x); }") Rcpp::cppFunction("IntegerVector doubleThisInt(IntegerVector x) { return(2*x); }") i <- 1:1e6 mb <- microbenchmark::microbenchmark(doubleThisNum(i), doubleThisInt(i), i*2, 2*i, i*2L, 2L*i, i+i, times=100) plot(mb, log="y", notch=TRUE)> (mb <- microbenchmark(doubleThis(i), i*2, 2*i, i*2L, 2L*i, i+i, times=2^12)) > ## Lynne (i7; FC 20), R Under development ... (2015-03-02 r67924): > ## Unit: nanoseconds > ## expr min lq mean median uq max neval cld > ## doubleThis(i) 762 985 1319.5974 1124 1338 17831 4096 b > ## i * 2 124 151 258.4419 164 221 22224 4096 a > ## 2 * i 127 154 266.4707 169 216 20213 4096 a > ## i * 2L 143 164 250.6057 181 234 16863 4096 a > ## 2L * i 144 177 269.5015 193 237 16119 4096 a > ## i + i 152 183 272.6179 199 243 10434 4096 a > > plot(mb, log="y", notch=TRUE) > ## hmm, looks like even the simple arithm. differ slightly ... > ## > ## ==> zoom in: > plot(mb, log="y", notch=TRUE, ylim = c(150,300)) > > dev.copy(png, file="mbenchm-doubling.png") > dev.off() # [ <- why do I need this here for png ??? ] > ##--> see the appended *png graphic > > Those who've learnt EDA or otherwise about boxplot notches, will > know that they provide somewhat informal but robust pairwise tests on > approximate 5% level. > From these, one *could* - possibly wrongly - conclude that > 'i * 2' is significantly faster than both 'i * 2L' and also > 'i + i' ---- which I find astonishing, given that i is integer here... > > Probably no reason for deep thoughts here, but if someone is > enticed, this maybe slightly interesting to read. > > Martin Maechler, ETH Zurich > > > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Possibly Parallel Threads
- R-devel does not update the C++ returned variables
- R-devel does not update the C++ returned variables
- R-devel does not update the C++ returned variables
- R-devel does not update the C++ returned variables
- invalid operands of types ‘SEXPREC*’ and ‘R_len_t’ to binary ‘operator/’ with Rcpp.