On 03/02/2015 01:00 PM, Hervé Pagès wrote:
Hi,
On 03/02/2015 12:18 PM, Dénes Tóth wrote:
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:10
Note 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.
The difference in speed is probably due to the fact that R does safe
arithmetic. C or C++ do not:
> doubleThisInt(i)
[1] 2147483642 2147483644 2147483646 NA -2147483646
-2147483644
> 2L * i
[1] 2147483642 2147483644 2147483646 NA NA NA
Warning message:
In 2L * i : NAs produced by integer overflow
That was with
i <- as.integer(2^30-4) + 1:6
Cheers,
H.
H.
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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
--
Hervé Pagès
Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024
E-mail: hpa...@fredhutch.org
Phone: (206) 667-5791
Fax: (206) 667-1319
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel