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 >
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 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 at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > ______________________________________________ > R-devel at 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: hpages at fredhutch.org Phone: (206) 667-5791 Fax: (206) 667-1319
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 overflowThat 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 at r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >> >> ______________________________________________ >> R-devel at 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: hpages at fredhutch.org Phone: (206) 667-5791 Fax: (206) 667-1319
Martin Maechler
2015-Mar-03 08:59 UTC
[Rd] R-devel does not update the C++ returned variables
>>>>> Herv? Pag?s <hpages at fredhutch.org> >>>>> on Mon, 2 Mar 2015 13:00:47 -0800 writes:> 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 > H. Exactly, excellent, Herv?! Luke also told me so in a private message. and 'i+i' is looking up 'i' twice which is relatively costly for very small i as in my example. This ("no safe integer arithmetic in C, but in R") is another good example {as Martin Morgan's} why using Rccp -- or .Call() directly -- may be a too sharp edged sword and maybe should be advocated for good programmers only. Martin >> >> 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 >>> >> >> ______________________________________________ >> R-devel at 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: hpages at fredhutch.org > Phone: (206) 667-5791 > Fax: (206) 667-1319