Hi Gabe,
On 05/30/2014 11:34 AM, Gabriel Becker wrote:
This isn't likely to make much difference in most cases, but calling a
function via :: can incur up to about twice the overhead on average
compared to calling an imported function
> fun1
function ()
file_ext("text.txt")
<environment: namespace:imptest>
> fun2
function ()
tools::file_ext("text.txt")
<environment: namespace:imptest>
> microbenchmark(fun1(), times=10000)
Unit: microseconds
expr min lq median uq max neval
fun1() 24.506 25.654 26.324 27.8795 154.001 10000
> microbenchmark(fun2(), times=10000)
Unit: microseconds
expr min lq median uq max neval
fun2() 42.723 46.6945 48.8685 52.0595 2021.91 10000
Interesting. Or with a void function so the timing more closely
reflects the time it takes to look up the symbol:
> void
function ()
NULL
<environment: namespace:S4Vectors>
> fun1
function ()
void()
<environment: namespace:IRanges>
> fun2
function ()
S4Vectors::void()
<environment: namespace:IRanges>
> microbenchmark(fun1(), times=10000)
Unit: nanoseconds
expr min lq median uq max neval
fun1() 261 268 270 301 11960 10000
> microbenchmark(fun2(), times=10000)
Unit: microseconds
expr min lq median uq max neval
fun2() 13.486 14.918 15.782 16.753 60542.19 10000
S4Vectors::void() is about 60x slower than void()!
Cheers,
H.
Also, if one uses roxygen2 (or even if one doesn't) ##'@importFrom above
the function doing the calling documents this.
And of course if you need to know where a function lives environment
will tell you.
~G
On Fri, May 30, 2014 at 10:00 AM, Hadley Wickham <h.wick...@gmail.com
<mailto:h.wick...@gmail.com>> wrote:
> There is at least one subtle consequence to keep in mind when doing
> this. Of course, whatever choice you make, if the whatever() function
> moves to a different package, this breaks your package.
> However, if you explicitly import the function, your package will
> break at load-time (which is good) and you'll only have to modify
> 1 line in the NAMESPACE file to fix it. But if you do
foo::whatever(),
> your package won't break at load-time, only at run-time. Also you'll
> have to edit all the calls to foo::whatever() to fix the package.
>
> Probably not a big deal, but in an environment like Bioconductor
where
> infrastructure classes and functions can be shared by hundreds of
> packages, having people use foo::whatever() in a systematic way would
> probably make maintenance a little bit more painful than it needs to
> be when the need arises to reorganize/refactor parts of the
> infrastructure. Also, the ability to quickly grep the NAMESPACE
> files of all BioC packages to see who imports what is very convenient
> in this situation.
OTOH, I think there's a big benefit to being able to read package code
and instantly know where a function comes from.
Personally, I found this outweighs the benefits that you outline:
* functions rarely move between packages, and gsubbing for pkga:foo to
pkgb:foo isn't hard
* it's not that much hard to grep for pkg::foo in R/* than it is to
grep NAMESPACE
Hadley
--
http://had.co.nz/
______________________________________________
R-devel@r-project.org <mailto:R-devel@r-project.org> mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
--
Gabriel Becker
Graduate Student
Statistics Department
University of California, Davis
--
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...@fhcrc.org
Phone: (206) 667-5791
Fax: (206) 667-1319
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel