commit 078f62faeec82821809104b2f2de23cb209a3ec4
parent a5d14654fd8c6c674170529a4c974380e3018957
Author: Federica Gazzelloni <61802414+Fgazzelloni@users.noreply.github.com>
Date:   Wed, 14 Dec 2022 19:03:41 +0100
chapter 23 (#42)
* chapter 23
* update description
Diffstat:
5 files changed, 166 insertions(+), 4 deletions(-)
diff --git a/23_Measuring_performance.Rmd b/23_Measuring_performance.Rmd
@@ -2,12 +2,159 @@
 
 **Learning objectives:**
 
-- THESE ARE NICE TO HAVE BUT NOT ABSOLUTELY NECESSARY
+- Understand how to improve your code for making it faster
+- Learn what are the tools for improving your code
+- Test how to profile your code
+
+
+## Introduction
+
+> "Before you can make your code faster, you first need to figure out what’s making it slow."
+
+
+```{r echo=FALSE, fig.align='center',fig.cap="SLOW DOWN TO LEARN HOW TO CODE FASTER | credits: packtpub.com"}
+knitr::include_graphics("images/23_code_faster.jpeg")
+```
+
+
+- **profile** your code: measure the run-time of each line of code using realistic inputs
+- **experiment** with alternatives to find faster code
+- **microbenchmark** to measure the difference in performance.
+
+
+
+## Profiling
+
+```{r message=FALSE, warning=FALSE, paged.print=FALSE}
+library(profvis)
+library(bench)
+```
+
+
+The tool to use is a **profiler**, it allows for **sampling** the code performance through stopping the execution of code every few milliseconds and recording all the steps.
+
+Example:
+
+```{r}
+f <- function() {
+  pause(0.1)
+  g()
+  h()
+}
+g <- function() {
+  pause(0.1)
+  h()
+}
+h <- function() {
+  pause(0.1)
+}
+```
+
+Profile the execution of f():
+
+    profvis::pause() is used instead of Sys.sleep()
+    profile f(), with utils::Rprof()
+    
+```{r}
+tmp <- tempfile()
+Rprof(tmp, interval = 0.1)
+f()
+Rprof(NULL)
+writeLines(readLines(tmp))
+```
+    
+    
+**Visualising profiles**
+
+Makes easier to build up a mental model of what you need to change:
+
+    profvis::profvis()
+    utils::summaryRprof()
+
+```{r}
+source("scripts/profiling-example.R")
+profvis(f())
+```
+
+**Memory profiling and the garbage collector**
+
+Profiling a loop that modifies an existing variable:
+```{r}
+profvis::profvis({
+  x <- integer()
+for (i in 1:1e4) {
+  x <- c(x, i)
+}
+})
+```
+
+You can figure out what is the source of the problem by looking at the memory column. In this case, **copy-on-modify** acts in each iteration of the loop creating another copy of x.
+
+
+**Limitations**
+
+- Profiling does not extend to C code
+- Anonymous functions are hard to figure out
+- Arguments are evaluated inside another function
+
+
+### Exercise
+```{r eval=FALSE}
+profvis::profvis({
+  f <- function(n = 1e5) {
+  x <- rep(1, n)
+  rm(x)
+}
+},torture = TRUE)
+```
+
+    ?rm()
+    
+[solution](https://advanced-r-solutions.rbind.io/measuring-performance.html)    
+    
+## Microbenchmarking
+
+
+*Measurement of the performance of a very small piece of code* is useful for comparing small snippets of code for specific tasks.
+
+```{r echo=FALSE, fig.align='center',fig.cap = "Credits: Google search-engine"}
+knitr::include_graphics("images/23_microbenchmarking.jpeg")
+```
+
+
+The {bench} package uses a high precision time.
+
+    bench::mark()
+    
+    
+```{r}
+library(bench)
+x <- runif(100)
+(lb <- bench::mark(
+  sqrt(x),
+  x ^ 0.5
+))
+```
+- heavily right-skewed distribution
+
+
+```{r}
+require(ggbeeswarm)
+plot(lb)
+```
+
+
+## Resources
+
+- [profvis package](https://rstudio.github.io/profvis/)
+- [bench package](https://cran.r-project.org/web/packages/bench/bench.pdf)
+- [solutions](https://advanced-r-solutions.rbind.io/measuring-performance.html)
+
+
+
+
 
-## SLIDE 1
 
-- ADD SLIDES AS SECTIONS (`##`).
-- TRY TO KEEP THEM RELATIVELY SLIDE-LIKE; THESE ARE NOTES, NOT THE BOOK ITSELF.
 
 ## Meeting Videos
 
diff --git a/DESCRIPTION b/DESCRIPTION
@@ -13,10 +13,12 @@ URL: https://r4ds.github.io/bookclub-advr, https://github.com/r4ds/bookclub-advr
 Depends:
     R (>= 3.1.0)
 Imports: 
+    bench,
     bookdown,
     deSolve,
     DiagrammeR,
     emoji,
+    ggbeeswarm,
     ggplot2,
     glue,
     lobstr,
@@ -24,6 +26,7 @@ Imports:
     memoise,
     palmerpenguins,
     patchwork,
+    profvis,
     purrr,
     R6,
     reshape2,
diff --git a/images/23_code_faster.jpeg b/images/23_code_faster.jpeg
Binary files differ.
diff --git a/images/23_microbenchmarking.jpeg b/images/23_microbenchmarking.jpeg
Binary files differ.
diff --git a/scripts/profiling-example.R b/scripts/profiling-example.R
@@ -0,0 +1,12 @@
+f <- function() {
+  pause(0.1)
+  g()
+  h()
+}
+g <- function() {
+  pause(0.1)
+  h()
+}
+h <- function() {
+  pause(0.1)
+}