diff --git a/Conditions.md b/Conditions.md
index bb4b9f98..d0a3cb0c 100644
--- a/Conditions.md
+++ b/Conditions.md
@@ -292,7 +292,7 @@ rlang::catch_cnd
#> return(NULL)
#> })))
#> }
-#>
+#>
#>
```
@@ -691,7 +691,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Control-flow.md b/Control-flow.md
index 2d402f2a..6aa7b7e6 100644
--- a/Control-flow.md
+++ b/Control-flow.md
@@ -246,7 +246,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Environments.md b/Environments.md
index 4b0d2e00..f19f5aae 100644
--- a/Environments.md
+++ b/Environments.md
@@ -40,7 +40,7 @@ library(rlang)
e <- env()
e$loop <- e
env_print(e)
-#>
+#>
#> Parent:
#> Bindings:
#> • loop:
@@ -51,8 +51,8 @@ The binding `loop` should have the same memory address as the environment `e`:
```r
lobstr::ref(e$loop)
-#> █ [1:0x558a72b692e8]
-#> └─loop = [1:0x558a72b692e8]
+#> █ [1:0x5592b255c2e8]
+#> └─loop = [1:0x5592b255c2e8]
```
**Q3.** Create a pair of environments as illustrated by this picture.
@@ -71,9 +71,9 @@ e2$deloop <- e1
# following should be the same
lobstr::obj_addrs(list(e1, e2$deloop))
-#> [1] "0x558a751c8be8" "0x558a751c8be8"
+#> [1] "0x5592b4bbb1e8" "0x5592b4bbb1e8"
lobstr::obj_addrs(list(e2, e1$loop))
-#> [1] "0x558a75216348" "0x558a75216348"
+#> [1] "0x5592b4c08948" "0x5592b4c08948"
```
**Q4.** Explain why `e[[1]]` and `e[c("a", "b")]` don't make sense when `e` is an environment.
@@ -300,7 +300,7 @@ fget("mean", inherits = FALSE)
fget("mean", inherits = TRUE)
#> function (x, ...)
#> UseMethod("mean")
-#>
+#>
#>
mean <- 5
@@ -506,7 +506,7 @@ rlang::caller_env
#> {
#> parent.frame(n + 1)
#> }
-#>
+#>
#>
```
@@ -559,7 +559,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Evaluation.md b/Evaluation.md
index 93469a5a..83d167ca 100644
--- a/Evaluation.md
+++ b/Evaluation.md
@@ -49,7 +49,7 @@ withr::with_tempdir(
foo()
}
)
-#>
+#>
#> Parent:
```
@@ -250,17 +250,17 @@ q1 <- new_quosure(expr(x), env(x = 1))
q1
#>
#> expr: ^x
-#> env: 0x56269fa39110
+#> env: 0x564fa1a3e9a0
q2 <- new_quosure(expr(x + !!q1), env(x = 10))
q2
#>
#> expr: ^x + (^x)
-#> env: 0x5626a008bd48
+#> env: 0x564fa20915d8
q3 <- new_quosure(expr(x + !!q2), env(x = 100))
q3
#>
#> expr: ^x + (^x + (^x))
-#> env: 0x5626a034a820
+#> env: 0x564fa23500b0
```
**A1.** Correctly predicted 😉
@@ -298,7 +298,7 @@ enenv(x)
foo <- function(x) enenv(x)
foo()
-#>
+#>
```
---
@@ -674,7 +674,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Expressions.md b/Expressions.md
index d5291c6c..e9a43887 100644
--- a/Expressions.md
+++ b/Expressions.md
@@ -374,7 +374,7 @@ call_standardise(quote(mean(x = 1:10, , TRUE)))
mean
#> function (x, ...)
#> UseMethod("mean")
-#>
+#>
#>
```
@@ -993,7 +993,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Function-factories.md b/Function-factories.md
index 9596903a..4e304a5c 100644
--- a/Function-factories.md
+++ b/Function-factories.md
@@ -21,7 +21,7 @@ library(ggplot2, warn.conflicts = FALSE)
force
#> function (x)
#> x
-#>
+#>
#>
```
@@ -47,8 +47,8 @@ f <- approxfun(x, y)
f
#> function (v)
#> .approxfun(x, y, v, method, yleft, yright, f, na.rm)
-#>
-#>
+#>
+#>
f(x)
#> [1] -0.7786629 -0.3894764 -2.0337983 -0.9823731 0.2478901
#> [6] -2.1038646 -0.3814180 2.0749198 1.0271384 0.4730142
@@ -212,15 +212,15 @@ new_counter3()
#> i <- i + 1
#> i
#> }
-#>
+#>
new_counter3()
#> function() {
#> i <- i + 1
#> i
#> }
-#>
-#>
+#>
+#>
```
---
@@ -258,7 +258,7 @@ ggplot2::label_bquote
#> }
#> structure(fun, class = "labeller")
#> }
-#>
+#>
#>
```
@@ -281,7 +281,7 @@ scales::number_format
#> scale_cut = scale_cut, trim = trim, ...)
#> }
#> }
-#>
+#>
#>
```
@@ -377,7 +377,7 @@ Let's have a look at one example with each:
```r
boxcox2(1)
#> function(x) (x^lambda - 1) / lambda
-#>
+#>
boxcox3(mtcars$wt)
#> function(lambda) {
@@ -387,7 +387,7 @@ boxcox3(mtcars$wt)
#> (x^lambda - 1) / lambda
#> }
#> }
-#>
+#>
```
As can be seen:
@@ -420,7 +420,7 @@ boot_permute(mtcars, "mpg")
#> col <- df[[var]]
#> col[sample(n, replace = TRUE)]
#> }
-#>
+#>
```
This is why we don't need to worry about a copy being made because the `df` in the function environment points to the memory address of the data frame. We can confirm this by comparing their memory addresses:
@@ -429,7 +429,7 @@ This is why we don't need to worry about a copy being made because the `df` in t
```r
boot_permute_env <- rlang::fn_env(boot_permute(mtcars, "mpg"))
rlang::env_print(boot_permute_env)
-#>
+#>
#> Parent:
#> Bindings:
#> • n:
@@ -488,8 +488,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#>
-#> 1 LL1 27.5µs 29.3µs 33174. 12.9KB 43.2
-#> 2 LL2 14.6µs 15.3µs 62143. 0B 49.8
+#> 1 LL1 28.3µs 30.2µs 31979. 12.9KB 41.6
+#> 2 LL2 14.6µs 15.7µs 60147. 0B 48.2
```
As can be seen, the second version is much faster than the first version.
@@ -515,16 +515,16 @@ generate_ll_benches <- function(n) {
#> # A tibble: 10 × 5
#> length expression min median `itr/sec`
#>
-#> 1 10 LL1 38.9µs 40.9µs 23209.
-#> 2 10 LL2 17.2µs 18µs 54710.
-#> 3 20 LL1 42.1µs 44µs 22427.
-#> 4 20 LL2 16.9µs 17.7µs 55356.
-#> 5 50 LL1 46.2µs 47.9µs 20558.
-#> 6 50 LL2 16.2µs 17.2µs 57361.
-#> 7 100 LL1 61.9µs 63.6µs 15410.
-#> 8 100 LL2 17.6µs 18.4µs 53603.
-#> 9 1000 LL1 854.3µs 872.3µs 1092.
-#> 10 1000 LL2 54.6µs 55.9µs 17653.
+#> 1 10 LL1 39.9µs 42.1µs 22543.
+#> 2 10 LL2 17.3µs 18.3µs 53968.
+#> 3 20 LL1 43µs 44.6µs 22159.
+#> 4 20 LL2 17.1µs 18µs 54815.
+#> 5 50 LL1 46.8µs 48.3µs 20374.
+#> 6 50 LL2 16.3µs 17.4µs 56753.
+#> 7 100 LL1 62.4µs 64.1µs 15369.
+#> 8 100 LL2 17.6µs 18.4µs 53652.
+#> 9 1000 LL1 857.4µs 965µs 1081.
+#> 10 1000 LL2 54.6µs 56.2µs 17530.
ggplot(
df_bench,
@@ -648,7 +648,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Function-factories_files/figure-html/Function-factories-28-1.png b/Function-factories_files/figure-html/Function-factories-28-1.png
index 1e1412cd..1ba1f6ed 100644
Binary files a/Function-factories_files/figure-html/Function-factories-28-1.png and b/Function-factories_files/figure-html/Function-factories-28-1.png differ
diff --git a/Function-operators.md b/Function-operators.md
index 2e4d964e..1b54d124 100644
--- a/Function-operators.md
+++ b/Function-operators.md
@@ -94,7 +94,7 @@ possibly
#> })
#> }
#> }
-#>
+#>
#>
```
@@ -120,7 +120,7 @@ safely
#> check_bool(quiet)
#> function(...) capture_error(.f(...), otherwise, quiet)
#> }
-#>
+#>
#>
purrr:::capture_error
@@ -132,7 +132,7 @@ purrr:::capture_error
#> list(result = otherwise, error = e)
#> })
#> }
-#>
+#>
#>
```
@@ -281,10 +281,10 @@ withr::with_tempfile("logfile", code = {
cat(readLines(logfile), sep = "\n")
})
-#> Function created at: 2023-12-31 00:43:08.117083
-#> Function called at: 2023-12-31 00:43:13.123988
-#> Function called at: 2023-12-31 00:43:18.129344
-#> Function called at: 2023-12-31 00:43:26.137767
+#> Function created at: 2024-01-07 00:44:00.426587
+#> Function called at: 2024-01-07 00:44:05.433612
+#> Function called at: 2024-01-07 00:44:10.439013
+#> Function called at: 2024-01-07 00:44:18.447574
```
---
@@ -333,7 +333,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Functionals.md b/Functionals.md
index 724c49ab..263cc0f3 100644
--- a/Functionals.md
+++ b/Functionals.md
@@ -36,7 +36,7 @@ map(x, 1)
as_mapper(1)
#> function (x, ...)
#> pluck_raw(x, list(1), .default = NULL)
-#>
+#>
map(x, list(2, 1))
#> [[1]]
@@ -47,7 +47,7 @@ map(x, list(2, 1))
as_mapper(list(2, 1))
#> function (x, ...)
#> pluck_raw(x, list(2, 1), .default = NULL)
-#>
+#>
# mapping by name -----------------------
@@ -65,7 +65,7 @@ map(y, "m")
as_mapper("m")
#> function (x, ...)
#> pluck_raw(x, list("m"), .default = NULL)
-#>
+#>
# mixing position and name
map(y, list(2, "m"))
@@ -77,7 +77,7 @@ map(y, list(2, "m"))
as_mapper(list(2, "m"))
#> function (x, ...)
#> pluck_raw(x, list(2, "m"), .default = NULL)
-#>
+#>
# compact functions ----------------------------
@@ -139,7 +139,7 @@ map(1:3, runif(2))
as_mapper(runif(2))
#> function (x, ...)
#> pluck_raw(x, list(0.597890264587477, 0.587997315218672), .default = NULL)
-#>
+#>
```
---
@@ -880,7 +880,7 @@ library(rlang)
e <- env("x" = 1, "y" = 2)
rlang::env_print(e)
-#>
+#>
#> Parent:
#> Bindings:
#> • x:
@@ -1015,7 +1015,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Functions.md b/Functions.md
index 9ba57553..6556d48b 100644
--- a/Functions.md
+++ b/Functions.md
@@ -20,7 +20,7 @@ library(tidyverse, warn.conflicts = FALSE)
match.fun("mean")
#> function (x, ...)
#> UseMethod("mean")
-#>
+#>
#>
```
@@ -347,7 +347,7 @@ names(primitives)
mean
#> function (x, ...)
#> UseMethod("mean")
-#>
+#>
#>
# other package function
@@ -356,7 +356,7 @@ purrr::map
#> {
#> map_("list", .x, .f, ..., .progress = .progress)
#> }
-#>
+#>
#>
```
@@ -559,7 +559,7 @@ f2 <- function(x = z) {
}
f2()
-#> [1] "0x5610bed32bc0" "0x5610bed32bc0"
+#> [1] "0x55734d8a0d10" "0x55734d8a0d10"
#> [1] 100
```
@@ -654,7 +654,7 @@ show_time <- function(x = stop("Error!")) {
}
show_time()
-#> [1] "2023-12-31 00:42:55 UTC"
+#> [1] "2024-01-07 00:43:46 UTC"
```
**A5.** Let's take this step-by-step.
@@ -874,7 +874,7 @@ withr::with_dir
#> on.exit(setwd(old))
#> force(code)
#> }
-#>
+#>
#>
```
@@ -958,7 +958,7 @@ capture.output
#> invisible(NULL)
#> else rval
#> }
-#>
+#>
#>
```
@@ -1298,7 +1298,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Names-values.md b/Names-values.md
index 472e65dd..a9337778 100644
--- a/Names-values.md
+++ b/Names-values.md
@@ -29,7 +29,7 @@ d <- 1:10
```r
obj_addrs <- obj_addrs(list(a, b, c))
unique(obj_addrs)
-#> [1] "0x556dced402c8"
+#> [1] "0x56426e6d12c8"
```
Except `d`, which is a different object, even if it has the same value as `a`, `b`, and `c`:
@@ -37,7 +37,7 @@ Except `d`, which is a different object, even if it has the same value as `a`, `
```r
obj_addr(d)
-#> [1] "0x556dce9f9fc8"
+#> [1] "0x56426e38afc8"
```
---
@@ -66,7 +66,7 @@ obj_addrs <- obj_addrs(list(
))
unique(obj_addrs)
-#> [1] "0x556dcc722500"
+#> [1] "0x56426c0b3500"
```
---
@@ -124,7 +124,7 @@ And as the docs mention (emphasis mine):
x <- 1:10
tracemem(x)
-#> [1] "<0x556dd0825628>"
+#> [1] "<0x5642701b6628>"
x <- x + 1
@@ -136,10 +136,10 @@ But since the object created in memory by `1:10` is not assigned a name, it can'
```r
obj_addr(1:10)
-#> [1] "0x556dd02fa0f8"
+#> [1] "0x56426fc8b0f8"
tracemem(1:10)
-#> [1] "<0x556dd03667a0>"
+#> [1] "<0x56426fcf77a0>"
```
---
@@ -163,11 +163,11 @@ x <- c(1L, 2L, 3L)
typeof(x)
#> [1] "integer"
tracemem(x)
-#> [1] "<0x556dd0baaad8>"
+#> [1] "<0x56427053bad8>"
x[[3]] <- 4
-#> tracemem[0x556dd0baaad8 -> 0x556dd0cd6558]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
-#> tracemem[0x556dd0cd6558 -> 0x556dd0ce41d8]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
+#> tracemem[0x56427053bad8 -> 0x564270667558]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
+#> tracemem[0x564270667558 -> 0x564270675188]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
untracemem(x)
typeof(x)
@@ -182,10 +182,10 @@ x <- c(1L, 2L, 3L)
typeof(x)
#> [1] "integer"
tracemem(x)
-#> [1] "<0x556dd11a3198>"
+#> [1] "<0x564270b34198>"
x[[3]] <- 4L
-#> tracemem[0x556dd11a3198 -> 0x556dd12cee18]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
+#> tracemem[0x564270b34198 -> 0x564270c5fe18]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
untracemem(x)
typeof(x)
@@ -216,20 +216,20 @@ b <- list(a, a)
c <- list(b, a, 1:10)
ref(a)
-#> [1:0x556dd198acc8]
+#> [1:0x56427131bcc8]
ref(b)
-#> █ [1:0x556dd1eb64c8]
-#> ├─[2:0x556dd198acc8]
-#> └─[2:0x556dd198acc8]
+#> █ [1:0x5642718493e8]
+#> ├─[2:0x56427131bcc8]
+#> └─[2:0x56427131bcc8]
ref(c)
-#> █ [1:0x556dd1f3ee48]
-#> ├─█ [2:0x556dd1eb64c8]
-#> │ ├─[3:0x556dd198acc8]
-#> │ └─[3:0x556dd198acc8]
-#> ├─[3:0x556dd198acc8]
-#> └─[4:0x556dd1f41178]
+#> █ [1:0x5642718cfda8]
+#> ├─█ [2:0x5642718493e8]
+#> │ ├─[3:0x56427131bcc8]
+#> │ └─[3:0x56427131bcc8]
+#> ├─[3:0x56427131bcc8]
+#> └─[4:0x5642718d2178]
```
Here is what we learn:
@@ -259,7 +259,7 @@ x
#> [[1]]
#> [1] 1 2 3 4 5 6 7 8 9 10
obj_addr(x)
-#> [1] "0x556dcfcf8e40"
+#> [1] "0x56426f689e78"
x[[2]] <- x
x
@@ -270,13 +270,13 @@ x
#> [[2]][[1]]
#> [1] 1 2 3 4 5 6 7 8 9 10
obj_addr(x)
-#> [1] "0x556dd04f3148"
+#> [1] "0x56426fe84148"
ref(x)
-#> █ [1:0x556dd04f3148]
-#> ├─[2:0x556dcf554b38]
-#> └─█ [3:0x556dcfcf8e40]
-#> └─[2:0x556dcf554b38]
+#> █ [1:0x56426fe84148]
+#> ├─[2:0x56426eee5b38]
+#> └─█ [3:0x56426f689e78]
+#> └─[2:0x56426eee5b38]
```
I don't have access to OmniGraffle software, so I am including here the figure from the [official solution manual](https://advanced-r-solutions.rbind.io/names-and-values.html#copy-on-modify):
@@ -425,16 +425,16 @@ x[[1]] <- x
x <- list()
obj_addr(x)
-#> [1] "0x556dd095be30"
+#> [1] "0x5642702ece68"
tracemem(x)
-#> [1] "<0x556dd095be30>"
+#> [1] "<0x5642702ece68>"
x[[1]] <- x
-#> tracemem[0x556dd095be30 -> 0x556dd02523e8]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
+#> tracemem[0x5642702ece68 -> 0x56426fbe3420]: eval eval eval_with_user_handlers withVisible withCallingHandlers handle timing_fn evaluate_call evaluate in_dir in_input_dir eng_r block_exec call_block process_group.block process_group withCallingHandlers withCallingHandlers handle_error process_file do.call eval eval eval eval eval.parent local
obj_addr(x[[1]])
-#> [1] "0x556dd095be30"
+#> [1] "0x5642702ece68"
```
---
@@ -552,7 +552,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Names-values_files/figure-html/Names-values-31-1.png b/Names-values_files/figure-html/Names-values-31-1.png
index 9030d805..8fe9b73c 100644
Binary files a/Names-values_files/figure-html/Names-values-31-1.png and b/Names-values_files/figure-html/Names-values-31-1.png differ
diff --git a/Perf-improve.md b/Perf-improve.md
index 2a20bf9a..533387ac 100644
--- a/Perf-improve.md
+++ b/Perf-improve.md
@@ -64,10 +64,10 @@ bench::mark(
#> # A tibble: 4 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 lm 860.49µs 897.15µs 1094. 1.27MB
-#> 2 speedglm 1.56ms 1.63ms 611. 75.01MB
-#> 3 biglm 767.92µs 797.64µs 1189. 589.1KB
-#> 4 fastLm 987.36µs 1.01ms 982. 4.48MB
+#> 1 lm 881.5µs 916.5µs 1045. 1.27MB
+#> 2 speedglm 1.6ms 1.66ms 601. 75.01MB
+#> 3 biglm 772.1µs 809.23µs 1174. 589.1KB
+#> 4 fastLm 993µs 1.02ms 978. 4.48MB
```
The results might change depending on the size of the dataset, with the performance benefits accruing bigger the dataset.
@@ -100,8 +100,8 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 base 1.14µs 1.18µs 796519. 2.8KB
-#> 2 fastmatch 990.93ns 1.04µs 929883. 2.66KB
+#> 1 base 1.18µs 1.24µs 756897. 2.8KB
+#> 2 fastmatch 1.02µs 1.06µs 904225. 2.66KB
```
But, with a larger vector, `fmatch()` is orders of magnitude faster! ⚡
@@ -120,8 +120,8 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 base 23.3ms 23.4ms 42.7 31.4MB
-#> 2 fastmatch 990.9ns 1.04µs 917170. 0B
+#> 1 base 20.6ms 21.95ms 43.0 31.4MB
+#> 2 fastmatch 992.1ns 1.04µs 897837. 0B
```
We can also look at the hash table:
@@ -200,10 +200,10 @@ bench::mark(
#> # A tibble: 4 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#>
-#> 1 as.POSIXct 29.97µs 31.6µs 31256. 0B 0
-#> 2 as.POSIXlt 20.65µs 21.83µs 45281. 0B 0
-#> 3 ymd_hms 2.22ms 2.29ms 432. 21.5KB 3.48
-#> 4 fastPOSIXct 1.17µs 1.22µs 779859. 0B 0
+#> 1 as.POSIXct 29.74µs 31.4µs 31531. 0B 0
+#> 2 as.POSIXlt 20.59µs 21.79µs 45434. 0B 0
+#> 3 ymd_hms 2.25ms 2.33ms 425. 21.5KB 3.43
+#> 4 fastPOSIXct 1.16µs 1.22µs 766780. 0B 0
```
There are many more packages that implement a way to convert from string to a date time object. For more, see [CRAN Task View: Time Series Analysis](https://cran.r-project.org/web/views/TimeSeries.html)
@@ -264,7 +264,7 @@ rowSums
#> else names(z) <- dimnames(x)[[1L]]
#> z
#> }
-#>
+#>
#>
```
@@ -275,7 +275,7 @@ rowSums
.rowSums
#> function (x, m, n, na.rm = FALSE)
#> .Internal(rowSums(x, m, n, na.rm))
-#>
+#>
#>
```
@@ -292,8 +292,8 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 rowSums 821µs 1.29ms 761. 859KB
-#> 2 .rowSums 818µs 1.28ms 837. 859KB
+#> 1 rowSums 821µs 1.29ms 859. 859KB
+#> 2 .rowSums 817µs 1.28ms 833. 859KB
```
**Q2.** Make a faster version of `chisq.test()` that only computes the chi-square test statistic when the input is two numeric vectors with no missing values. You can try simplifying `chisq.test()` or by coding from the [mathematical definition](http://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test).
@@ -360,8 +360,8 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 base 904µs 927µs 1008. 1.57MB
-#> 2 custom 708µs 721µs 1376. 1.13MB
+#> 1 base 906µs 926µs 1071. 1.57MB
+#> 2 custom 706µs 722µs 1371. 1.13MB
```
**Q3.** Can you make a faster version of `table()` for the case of an input of two integer vectors with no missing values? Can you use it to speed up your chi-square test?
@@ -418,8 +418,8 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 base 638µs 652µs 1519. 960KB
-#> 2 custom 355µs 362µs 2736. 488KB
+#> 1 base 638µs 653µs 1515. 960KB
+#> 2 custom 354µs 359µs 2730. 488KB
```
We can also use this function in our custom chi-squared test function and see if the performance improves any further:
@@ -477,8 +477,8 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 base 909µs 940µs 1059. 1.28MB
-#> 2 custom 418µs 427µs 2314. 594.45KB
+#> 1 base 912µs 940µs 1057. 1.28MB
+#> 2 custom 420µs 429µs 2296. 594.45KB
```
## Exercises 24.5.1
@@ -601,6 +601,6 @@ bench::mark(
#> # A tibble: 2 × 5
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 crossprod(x, w)[[1]] 871ns 922ns 1001700. 0B
-#> 2 sum(x * w)[[1]] 460ns 511ns 1796479. 0B
+#> 1 crossprod(x, w)[[1]] 901ns 961ns 966191. 0B
+#> 2 sum(x * w)[[1]] 461ns 511ns 1759060. 0B
```
diff --git a/Perf-improve_files/figure-html/Perf-improve-28-1.png b/Perf-improve_files/figure-html/Perf-improve-28-1.png
index 6b43e418..27963a50 100644
Binary files a/Perf-improve_files/figure-html/Perf-improve-28-1.png and b/Perf-improve_files/figure-html/Perf-improve-28-1.png differ
diff --git a/Perf-measure.md b/Perf-measure.md
index 6afd518b..dc2143c8 100644
--- a/Perf-measure.md
+++ b/Perf-measure.md
@@ -68,7 +68,7 @@ rm
#> }
#> .Internal(remove(list, envir, inherits))
#> }
-#>
+#>
#>
```
@@ -144,8 +144,8 @@ full_join(t_bench_df, t_systime_df, by = "expression")
#> # A tibble: 2 × 4
#> expression bench_mean systime_with_gc systime_with_nogc
#>
-#> 1 sqrt(x) 670.07ns 0.629 0.443
-#> 2 x^0.5 2.19µs 2.01 2.02
+#> 1 sqrt(x) 677.2ns 0.629 0.428
+#> 2 x^0.5 2.23µs 2.02 2.00
```
The comparison reveals that these two approaches yield quite similar results. Slight differences in exact values is possibly due to differences in the precision of timers used internally by these functions.
@@ -180,10 +180,10 @@ bench::mark(
#> # A tibble: 4 × 2
#> expression median
#>
-#> 1 sqrt(x) 3.03µs
-#> 2 exp(log(x)/2) 12.62µs
-#> 3 x^0.5 18.86µs
-#> 4 x^(1/2) 19µs
+#> 1 sqrt(x) 3.02µs
+#> 2 exp(log(x)/2) 12.66µs
+#> 3 x^0.5 18.96µs
+#> 4 x^(1/2) 19.01µs
```
The specialized primitive function `sqrt()` (written in `C`) is the fastest way to compute square root.
@@ -205,7 +205,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Quotation.md b/Quotation.md
index 4f9eec32..f71682ea 100644
--- a/Quotation.md
+++ b/Quotation.md
@@ -171,7 +171,7 @@ rlang::expr
#> {
#> enexpr(expr)
#> }
-#>
+#>
#>
```
@@ -193,7 +193,7 @@ rlang::enexpr
#> {
#> .Call(ffi_enexpr, substitute(arg), parent.frame())
#> }
-#>
+#>
#>
```
@@ -824,7 +824,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz UTC
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/R6.md b/R6.md
index 988cee34..4c63dc0e 100644
--- a/R6.md
+++ b/R6.md
@@ -288,7 +288,7 @@ typeof(myExample)
#> [1] "environment"
rlang::env_print(myExample)
-#> [L]
+#> [L]
#> Parent:
#> Class: Example, R6
#> Bindings:
@@ -556,7 +556,7 @@ gc()
#> [1] "Closing the file connection!"
#> used (Mb) gc trigger (Mb) max used (Mb)
#> Ncells 746818 39.9 1365334 73 1365334 73.0
-#> Vcells 1372826 10.5 8388608 64 2594866 19.8
+#> Vcells 1372826 10.5 8388608 64 2594870 19.8
```
## Session information
@@ -574,7 +574,7 @@ sessioninfo::session_info(include_base = TRUE)
#> collate C.UTF-8
#> ctype C.UTF-8
#> tz Europe/Berlin
-#> date 2023-12-31
+#> date 2024-01-07
#> pandoc 3.1.8 @ /usr/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────
diff --git a/Rcpp.md b/Rcpp.md
index 73dfc463..7c75ddcc 100644
--- a/Rcpp.md
+++ b/Rcpp.md
@@ -216,12 +216,12 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min
#>
-#> 1 all(c(rep(TRUE, 1000), rep(FALSE, 1000))) 6.16µs
-#> 2 allC(c(rep(TRUE, 1000), rep(FALSE, 1000))) 8.59µs
+#> 1 all(c(rep(TRUE, 1000), rep(FALSE, 1000))) 6.13µs
+#> 2 allC(c(rep(TRUE, 1000), rep(FALSE, 1000))) 8.73µs
#> median `itr/sec` mem_alloc `gc/sec`
#>
-#> 1 6.46µs 152676. 15.8KB 0
-#> 2 8.95µs 109377. 18.3KB 0
+#> 1 6.49µs 152211. 15.8KB 0
+#> 2 9.15µs 106881. 18.3KB 0
```
- `cumprod()`
@@ -263,8 +263,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 cumprod(v1) 110.01ns 130.04ns 6991133. 0B
-#> 2 cumprodC(v1) 1.44µs 1.53µs 619348. 6.62KB
+#> 1 cumprod(v1) 89.99ns 101.05ns 8156808. 0B
+#> 2 cumprodC(v1) 1.45µs 1.55µs 612672. 6.62KB
#> `gc/sec`
#>
#> 1 0
@@ -310,8 +310,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#>
-#> 1 cummin(v1) 130.97ns 151.57ns 5389797. 0B 0
-#> 2 cumminC(v1) 1.52µs 1.83µs 514890. 6.62KB 0
+#> 1 cummin(v1) 120.02ns 131.08ns 5672695. 0B 0
+#> 2 cumminC(v1) 1.56µs 1.87µs 507394. 6.62KB 0
```
- `cummaxC()`
@@ -353,8 +353,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#>
-#> 1 cummax(v1) 110.01ns 120.14ns 6760800. 0B 0
-#> 2 cummaxC(v1) 1.55µs 1.72µs 549982. 6.62KB 0
+#> 1 cummax(v1) 110.01ns 121.07ns 6496158. 0B 0
+#> 2 cummaxC(v1) 1.58µs 1.76µs 545922. 6.62KB 0
```
- `diff()`
@@ -417,8 +417,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc
#>
-#> 1 diff(v1, 2) 3.78µs 4.44µs 218299. 0B
-#> 2 diffC(v1, 2) 1.91µs 2.12µs 450551. 2.49KB
+#> 1 diff(v1, 2) 3.88µs 4.46µs 217285. 0B
+#> 2 diffC(v1, 2) 1.89µs 2.13µs 452394. 2.49KB
#> `gc/sec`
#>
#> 1 0
@@ -464,8 +464,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#>