Skip to content

[Rcpp-devel] Rcpp ISNAN slower than C ISNAN?

3 messages · Christian Gunning, Johannes Kruisselbrink

#
Understood - just wanted to highlight the existence of Rcpp::is_nan /
Rcpp::any in case they were broadly relevant.
Take care to distinguish the R-core ISNAN macro, the R_IsNaN function,
and the Rcpp::isNaN template function. Asides from sugar-stuff, all
the examples discussed here so far address the performance of R-core
ISNAN, given doubles that are accessed via Rcpp, correct?

I'm not qualified to answer, but your example piqued my interest.
Based on your previous email, I'm guessing you found this?

"Currently in C code ISNAN is a macro calling isnan. (Since this gives
problems on some C++ systems, if the R headers is called from C++ code
a function call is used.) "
http://www.hep.by/gnu/r-patched/r-exts/R-exts_133.html

Definitions from the horse's mouth:
https://github.com/wch/r-source/blob/trunk/src/include/R_ext/Arith.h#L66

Based on the above, I added permutations to a *very* minimal test (no
return val, etc) that include Romain's suggestion:
https://github.com/helmingstay/rcpp-timings/tree/master/minimal
## source('benchmarks.r')

I see that:
A) the sugar expression in slow
B) based on timings, ISNAN appears to call R_isnancpp, which is slow
C) std::count_if yields a modest improvement given B)
D) Using an inline function matching the definintion of ISNAN used in
a C envir [i.e., "isnan(xx)!=0", using math.h] appears to incur no
cost at all (example CountNans_expr)

This doesn't get to the *why*, but perhaps addresses the question of
intrinsic limitations in Rcpp. Perhaps others can comment on whether
D) is equivalent to driving without a seatbelt.

hth,
-Christian
#
Good point. Actually, I didn't even realize there were so many is-nan 
functions to choose from. But indeed, we used the R-core ISNAN function 
on doubles accessed via Rcpp.
This was also pointed out by Bill Dunlap and indeed seems to be the 
explanation for the difference. Very unfortunate, because it was our 
most preferred ISNAN function. Seems that those "some C++ systems" ruin 
it for others.
Wow, thank you for the thorough comparison. I ran some tests myself 
based on your code. It seems that I cannot get the "CountNans_expr" 
version to compile, any ideas?  Same problem with the Rcpp sugar isnan 
version.

The std::isnan version, however, does work and, on my machine, actually 
outperforms the call function. So performance-wise this is a very 
interesting candidate. How safe is it to use this function? Would that 
also be a "driving-without-seatbelts" equivalent?
#
On Wed, Dec 14, 2016 at 12:23 PM, Johannes Kruisselbrink
<johannes at kruisselbrink.eu> wrote:
Me either :)
Of course, the above isn't particular to Rcpp, but I found that
tracking down the underlying machinery of ISNAN in the context of Rcpp
to be an interesting and useful exercise.
[...]
Can you be more specific?
Just to clarify, R's NA is subset of ieee NaN.  So std::isnan catches
both NAs and NaNs.  If you need to manually catch *just* NAs, then it
looks like you need to return to an R-core solution (please do correct
me if I muxed this up).
Ref: https://github.com/wch/r-source/blob/trunk/src/main/arithmetic.c#L108

best,
Christian