From 83cc11639d0912ff0cffe3f1ec5e7ca9eb53cb26 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Fri, 16 May 2014 00:15:07 -0500 Subject: [PATCH] Updates to performance doc --- vignettes/Performance.Rmd | 49 ++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/vignettes/Performance.Rmd b/vignettes/Performance.Rmd index b295d06..5b42014 100644 --- a/vignettes/Performance.Rmd +++ b/vignettes/Performance.Rmd @@ -1,6 +1,9 @@ --- title: "Reference class performance tests" -output: html_document +output: + html_document: + theme: spacelab + toc: yes --- +Reference classes in R are very useful for some situations, but they don't come for free. In this document, we'll explore the costs in memory and speed of standard R reference classes vs. other reference objects which are created in different ways. + +We won't cover the other major cost of reference classes, which is the complexity and fickleness of working with S4 (since reference classes are built on S4). + + ```{r} +# Some setup stuff library(microbenchmark) library(pryr) -library(testclasses) +library(testclasses) # For Winston's simple reference classes ``` -## Class definitions -Here are a number of ways of creating reference objects in R, starting with the most complicated (standard R reference classes) and ending with the simplest (an environment created by a closure). +***** + +Class definitions +================= -### Standard R reference class +Here are a number of ways of creating reference objects in R, starting with the most complicated (standard R reference class) and ending with the simplest (an environment created by a closure). + +## Standard R reference class ```{r} A_rc <- setRefClass("A_rc", @@ -29,7 +42,7 @@ A_rc <- setRefClass("A_rc", ) ``` -### Winston's simple reference class +## Winston's simple reference class ```{r} B_wrc <- createRefClass("B_wrc", @@ -47,7 +60,7 @@ Objects of this type also have an automatically-created `self` member: print(B_wrc$new()) ``` -### Environment created by a closure, with class attribute +## Environment created by a closure, with class attribute ```{r} C_closure_class <- function(x = 1) { @@ -58,7 +71,7 @@ C_closure_class <- function(x = 1) { This doesn't have a `self` member, although that could be added. -### Environment created by a closure, without class attribute +## Environment created by a closure, without class attribute This is the simplest type of reference object: @@ -69,6 +82,10 @@ D_closure_noclass <- function(x = 1) { } ``` +***** + +Tests +===== ## Memory footprint @@ -244,3 +261,19 @@ microbenchmark( env_class = env_class$x ) ``` + +***** + +Wrap-up +======= + +Standard reference class objects take more memory and are slower than other, simpler types of reference objects. They do provide additional features, such as type checking of fields and class inheritance, but these aren't, in my opinion, enough to offset the performance penalty and especially the pain of dealing with S4 (which reference classes are built on). Type checking of fields is only a minor benefit, and it would be simple to add inheritance to Winston's reference class implementation. It would also be simple to implement private and public members, though there would be a small performance penalty. + +Another drawback to standard R reference class objects is it's not entirely clear how they work, as many advanced R developers can attest. The other types of reference objects used here are simple and can be understood completely, as long as one understands how environments work. + +Appendix +======== + +```{r} +sessionInfo() +```