insitu
insitu
provides some functions for modifying vectors in-situ (in place)
without allocating a new vector.
This is an experimental package I wrote to try and figure out just how fast things could be in R.
Warning: Modifying vectors in-situ can be fast, but doing so violates some very strong norms within R internals.
Warning: Unless you are very confident on who has references to your data, do not use this package for in-place modification.
Modifying vectors in-place
Pros of modifying in-situ
- Often faster as there is reduced memory allocation (and also reduced pressure on the garbage collector)
- Often faster as there is no copying from the original vector into a new vector
- By using C, we can override the copy-on-modify semantics usually used in R (regardless of how many references exist to the given object)
Cons of modifying in-situ
- Normal R copy-on-modify behaviour is not followed - this will be a point of confusion as essentially everything in R uses copy-on-modify and not modification in-place.
- Copying and allocating vectors is already very fast. It only takes a few microseconds to allocate memory for a vector of 1000 elements and assign new values into it. The speed saved by switching to in-situ modification will only possibly be useful if this operations is performed many, many times.
In the words of Luke Tierney in his User2020 keynote:
You should never modify something without duplicating it.
This package ignores this advice. Beware.
What’s in the box
insitu | description | integer | real | character |
---|---|---|---|---|
insitu_fill(x, value) | Fill vector with the given value | Yes | Yes | Yes |
insitu_fill_runif(x, lower, upper) | Fill vector with uniform random numbers | Yes | Yes | |
insitu_fill_runif_fast(x, lower, upper) | Fill vector with uniform random numbers | Yes | Yes | |
insitu_replace(x, pos, values) | Replace values in x with given values starting from the given position | Yes | Yes | Yes |
insitu_reverse(x) | Reverse vector | Yes | Yes | Yes |
insitu_shuffle(x) | Shuffle the elements of a vector | Yes | Yes | Yes |
insitu_shuffle_fast(x) | Shuffle the elements of a vector | Yes | Yes | Yes |
insitu_sort(x) | Sort the elements of a vector | Yes | Yes | |
Fast Variants
The _fast
versions of some functions use their own random-number generator
rather than the one supplied in R. This generator is lehmer64.
It is very fast, but has different properties from R’s built in random
number generator. Use with caution.
ALTREP utils
is_altrep(x)
tests whether an object is an ALTREPis_mutable(x)
tests whether an object is mutable in-place by checking its reference countget_refcnt(x)
returns the reference count for the object
Installation
You can install from GitHub with:
# install.package('remotes')
remotes::install_github('coolbutuseless/insitu')
Future possibilities
- In-place radix sort - instead of using
qsort()
cummin
,cummax
etcnegate
diff
In-situ Replacement
insitu_replace()
is analogous to replace()
but replaces values in the current
vector rather than creating a new one.
x <- integer(10)
insitu_replace(x, 6, 1:5)
x
[1] 0 0 0 0 0 1 2 3 4 5
Click to show/hide benchmark code & results
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Assign values into a vector
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
N = c(1e1, 1e2, 1e3, 1e4, 1e5, 1e6)
res_rel <- bench::press(
N = N,
{
x <- numeric(N)
x[1] <- x[1]
idx <- seq(1, N/2)
ins <- as.numeric(idx)
bench::mark(
replace(x, idx, ins),
insitu_replace(x, 1, ins),
check = TRUE,
relative = TRUE
)
}
)
res_rel %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
replace(x, idx, ins) | 1.160156 | 1.106230 | 1.000000 | NaN |
insitu_replace(x, 1, ins) | 1.000000 | 1.000000 | 1.118310 | NaN |
replace(x, idx, ins) | 1.797336 | 2.029647 | 1.000000 | 2.446429 |
insitu_replace(x, 1, ins) | 1.000000 | 1.000000 | 2.281246 | 1.000000 |
replace(x, idx, ins) | 5.195353 | 7.137832 | 1.000000 | 2.494071 |
insitu_replace(x, 1, ins) | 1.000000 | 1.000000 | 6.741992 | 1.000000 |
replace(x, idx, ins) | 15.738677 | 25.238643 | 1.000000 | 2.499401 |
insitu_replace(x, 1, ins) | 1.000000 | 1.000000 | 24.600466 | 1.000000 |
replace(x, idx, ins) | 19.240119 | 31.171246 | 1.000000 | 2.499940 |
insitu_replace(x, 1, ins) | 1.000000 | 1.000000 | 27.534510 | 1.000000 |
replace(x, idx, ins) | 19.387400 | 18.192379 | 1.000000 | 2.499994 |
insitu_replace(x, 1, ins) | 1.000000 | 1.000000 | 17.034955 | 1.000000 |
res_abs <- bench::press(
N = N,
{
x <- numeric(N)
x[1] <- x[1]
idx <- seq(1, N/2)
ins <- as.numeric(idx)
bench::mark(
replace(x, idx, ins),
insitu_replace(x, 1, ins),
check = TRUE,
relative = FALSE
)
}
)
res_abs %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
replace(x, idx, ins) | 1.15µs | 1.33µs | 604227.9275 | 0B |
insitu_replace(x, 1, ins) | 1.01µs | 1.23µs | 626725.4925 | 0B |
replace(x, idx, ins) | 1.92µs | 2.62µs | 320836.0319 | 1.07KB |
insitu_replace(x, 1, ins) | 1.05µs | 1.26µs | 681850.9878 | 448B |
replace(x, idx, ins) | 6.01µs | 7.62µs | 113786.9416 | 9.86KB |
insitu_replace(x, 1, ins) | 1.16µs | 1.31µs | 711556.3865 | 3.95KB |
replace(x, idx, ins) | 42.78µs | 80.93µs | 11838.8043 | 97.75KB |
insitu_replace(x, 1, ins) | 2.8µs | 3.13µs | 299449.9164 | 39.11KB |
replace(x, idx, ins) | 417.16µs | 726.44µs | 1459.5060 | 976.66KB |
insitu_replace(x, 1, ins) | 21.53µs | 24.7µs | 37556.2759 | 390.67KB |
replace(x, idx, ins) | 4.68ms | 5.03ms | 184.7498 | 9.54MB |
insitu_replace(x, 1, ins) | 245.95µs | 287.6µs | 2939.2212 | 3.81MB |
In-situ fill
insitu_fill()
is analogous to replace()
but assigns the value into the current
vector rather than creating a new one.
x <- integer(10)
insitu_fill(x, 3L)
x
[1] 3 3 3 3 3 3 3 3 3 3
Click to show/hide benchmark code & results
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Assign values into a vector
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# N = c(1e1, 1e2, 1e3, 1e4, 1e5, 1e6)
res_rel <- bench::press(
N = N,
{
x <- numeric(N)
idx <- 1:N
ins <- 99
bench::mark(
replace(x, idx, ins),
insitu_fill(x, ins),
check = TRUE,
relative = TRUE
)
}
)
res_rel %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
replace(x, idx, ins) | 1.229236 | 1.298578 | 1.000000 | NaN |
insitu_fill(x, ins) | 1.000000 | 1.000000 | 1.326658 | NaN |
replace(x, idx, ins) | 1.363341 | 1.667515 | 1.000000 | Inf |
insitu_fill(x, ins) | 1.000000 | 1.000000 | 1.830421 | NaN |
replace(x, idx, ins) | 1.000000 | 1.181148 | 1.000000 | Inf |
insitu_fill(x, ins) | 1.060364 | 1.000000 | 1.324551 | NaN |
replace(x, idx, ins) | 1.000000 | 1.590073 | 1.000000 | Inf |
insitu_fill(x, ins) | 1.347507 | 1.000000 | 1.572959 | NaN |
replace(x, idx, ins) | 1.000000 | 1.455272 | 1.000000 | Inf |
insitu_fill(x, ins) | 1.343936 | 1.000000 | 1.357076 | NaN |
replace(x, idx, ins) | 1.000000 | 1.000000 | 1.013211 | Inf |
insitu_fill(x, ins) | 1.217040 | 1.111741 | 1.000000 | NaN |
res_abs <- bench::press(
N = N,
{
x <- numeric(N)
idx <- 1:N
ins <- 99
bench::mark(
replace(x, idx, ins),
insitu_fill(x, ins),
check = TRUE,
relative = FALSE
)
}
)
res_abs %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
replace(x, idx, ins) | 1.15µs | 1.35µs | 662250.3834 | 0B |
insitu_fill(x, ins) | 867ns | 1.05µs | 850804.0257 | 0B |
replace(x, idx, ins) | 1.67µs | 2.02µs | 386154.9397 | 1.27KB |
insitu_fill(x, ins) | 1.26µs | 1.36µs | 597002.8780 | 0B |
replace(x, idx, ins) | 4.29µs | 5.64µs | 155360.2575 | 11.81KB |
insitu_fill(x, ins) | 4.72µs | 4.92µs | 194406.1723 | 0B |
replace(x, idx, ins) | 29.01µs | 66.16µs | 14534.3837 | 117.28KB |
insitu_fill(x, ins) | 38.24µs | 41.7µs | 22958.4854 | 0B |
replace(x, idx, ins) | 273.27µs | 621.43µs | 1624.1870 | 1.15MB |
insitu_fill(x, ins) | 380.05µs | 420.89µs | 2334.8499 | 0B |
replace(x, idx, ins) | 3.25ms | 3.7ms | 241.1781 | 11.44MB |
insitu_fill(x, ins) | 3.69ms | 4.21ms | 235.6181 | 0B |
In-situ sort
insitu_sort()
is analogous to sort()
but sorts values in the current
vector rather than creating a new one.
x <- sample(10)
insitu_sort(x)
x
[1] 1 2 3 4 5 6 7 8 9 10
Click to show/hide benchmark code & results
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Assign values into a vector
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# N = c(1e1, 1e2, 1e3, 1e4, 1e5, 1e6)
res_rel <- bench::press(
N = N,
{
x <- runif(N)
bench::mark(
sort(x),
insitu_sort(x),
check = TRUE,
relative = TRUE
)
}
)
res_rel %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
sort(x) | 44.192865 | 42.981013 | 1.000000 | NaN |
insitu_sort(x) | 1.000000 | 1.000000 | 40.303405 | NaN |
sort(x) | 26.989432 | 28.228392 | 1.000000 | Inf |
insitu_sort(x) | 1.000000 | 1.000000 | 29.388349 | NaN |
sort(x) | 6.541023 | 7.107368 | 1.000000 | Inf |
insitu_sort(x) | 1.000000 | 1.000000 | 7.478798 | NaN |
sort(x) | 1.937674 | 2.525904 | 1.000000 | Inf |
insitu_sort(x) | 1.000000 | 1.000000 | 2.521864 | NaN |
sort(x) | 1.064732 | 1.699909 | 1.000000 | Inf |
insitu_sort(x) | 1.000000 | 1.000000 | 1.669044 | NaN |
sort(x) | 1.025600 | 1.175356 | 1.000000 | Inf |
insitu_sort(x) | 1.000000 | 1.000000 | 1.330278 | NaN |
res_abs <- bench::press(
N = N,
{
x <- runif(N)
bench::mark(
sort(x),
insitu_sort(x),
check = TRUE,
relative = FALSE
)
}
)
res_abs %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
sort(x) | 40.45µs | 47.63µs | 19323.2410 | 0B |
insitu_sort(x) | 899ns | 1.05µs | 823655.6466 | 0B |
sort(x) | 41.66µs | 49.55µs | 17223.6604 | 1.27KB |
insitu_sort(x) | 1.51µs | 1.73µs | 530651.7167 | 0B |
sort(x) | 47.28µs | 57.11µs | 15012.7291 | 11.81KB |
insitu_sort(x) | 7.04µs | 7.86µs | 109586.8553 | 0B |
sort(x) | 107.95µs | 173.51µs | 5329.9525 | 117.28KB |
insitu_sort(x) | 62.18µs | 65.97µs | 14349.4585 | 0B |
sort(x) | 653.57µs | 1.2ms | 832.5820 | 1.15MB |
insitu_sort(x) | 591.85µs | 674.37µs | 1450.3867 | 0B |
sort(x) | 6.83ms | 9.13ms | 110.9861 | 11.44MB |
insitu_sort(x) | 6ms | 6.54ms | 151.5278 | 0B |
In-situ Shuffle
insitu_shuffle()
is analogous to sample()
but shuffles values in the current
vector rather than creating a new one.
x <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
insitu_shuffle(x)
x
[1] 9 6 0 3 5 7 8 1 4 2
Click to show/hide benchmark code & results
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Assign values into a vector
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# N = c(1e1, 1e2, 1e3, 1e4, 1e5, 1e6)
res_rel <- bench::press(
N = N,
{
x <- runif(N)
bench::mark(
sample(x),
insitu_shuffle(x),
insitu_shuffle_fast(x),
check = FALSE,
relative = TRUE
)
}
)
res_rel %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
sample(x) | 7.385214 | 7.171458 | 1.000000 | Inf |
insitu_shuffle(x) | 1.000000 | 1.000000 | 7.053456 | NaN |
insitu_shuffle_fast(x) | 2.315175 | 2.382957 | 2.972455 | Inf |
sample(x) | 5.043932 | 6.137506 | 1.000000 | Inf |
insitu_shuffle(x) | 1.000000 | 1.000000 | 5.700903 | NaN |
insitu_shuffle_fast(x) | 1.163097 | 1.310498 | 4.336377 | Inf |
sample(x) | 7.971023 | 7.385535 | 1.000000 | Inf |
insitu_shuffle(x) | 2.233688 | 2.114623 | 3.455347 | NaN |
insitu_shuffle_fast(x) | 1.000000 | 1.000000 | 7.182072 | Inf |
sample(x) | 11.935903 | 13.344195 | 1.000000 | Inf |
insitu_shuffle(x) | 3.137795 | 3.202304 | 4.109921 | NaN |
insitu_shuffle_fast(x) | 1.000000 | 1.000000 | 12.875612 | Inf |
sample(x) | 14.665743 | 15.785546 | 1.000000 | Inf |
insitu_shuffle(x) | 3.228209 | 3.517930 | 4.345945 | NaN |
insitu_shuffle_fast(x) | 1.000000 | 1.000000 | 15.129547 | Inf |
sample(x) | 12.858372 | 12.382391 | 1.000000 | Inf |
insitu_shuffle(x) | 2.860528 | 3.340090 | 3.774192 | NaN |
insitu_shuffle_fast(x) | 1.000000 | 1.000000 | 10.934830 | Inf |
res_abs <- bench::press(
N = N,
{
x <- runif(N)
bench::mark(
sample(x),
insitu_shuffle(x),
insitu_shuffle_fast(x),
check = FALSE,
relative = FALSE
)
}
)
res_abs %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
sample(x) | 5.89µs | 7.16µs | 129084.90804 | 2.49KB |
insitu_shuffle(x) | 818ns | 975ns | 952295.33521 | 0B |
insitu_shuffle_fast(x) | 1.77µs | 2.26µs | 414345.47824 | 2.49KB |
sample(x) | 9.3µs | 11.41µs | 83312.86336 | 4.2KB |
insitu_shuffle(x) | 1.74µs | 2.01µs | 446962.15223 | 0B |
insitu_shuffle_fast(x) | 2.03µs | 2.58µs | 364783.29064 | 2.49KB |
sample(x) | 41.86µs | 46.39µs | 20845.99544 | 18.27KB |
insitu_shuffle(x) | 11.91µs | 13.28µs | 71481.19180 | 0B |
insitu_shuffle_fast(x) | 5.28µs | 6.12µs | 150911.04998 | 2.49KB |
sample(x) | 419.28µs | 500.08µs | 1956.51662 | 158.89KB |
insitu_shuffle(x) | 112.27µs | 120.26µs | 7967.50222 | 0B |
insitu_shuffle_fast(x) | 35.59µs | 38.02µs | 24551.59483 | 2.49KB |
sample(x) | 5.54ms | 6.69ms | 143.55062 | 1.53MB |
insitu_shuffle(x) | 1.21ms | 1.39ms | 699.63921 | 0B |
insitu_shuffle_fast(x) | 375.44µs | 391.24µs | 2437.92941 | 2.49KB |
sample(x) | 81.23ms | 83.06ms | 11.88900 | 15.26MB |
insitu_shuffle(x) | 17.31ms | 22.98ms | 44.18255 | 0B |
insitu_shuffle_fast(x) | 6.15ms | 7.09ms | 132.75626 | 2.49KB |
In-situ Reverse
insitu_reverse()
is analogous to rev()
but reverses values in the current
vector rather than creating a new one.
x <- c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
insitu_reverse(x)
x
[1] 9 8 7 6 5 4 3 2 1 0
Click to show/hide benchmark code & results
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Assign values into a vector
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# N = c(1e1, 1e2, 1e3, 1e4, 1e5, 1e6)
res_rel <- bench::press(
N = N,
{
x <- runif(N)
bench::mark(
rev(x),
insitu_reverse(x),
check = TRUE,
relative = TRUE
)
}
)
res_rel %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
rev(x) | 4.001531 | 4.259724 | 1.000000 | NaN |
insitu_reverse(x) | 1.000000 | 1.000000 | 4.248889 | NaN |
rev(x) | 4.519830 | 5.314951 | 1.000000 | Inf |
insitu_reverse(x) | 1.000000 | 1.000000 | 5.458907 | NaN |
rev(x) | 5.461066 | 6.297345 | 1.000000 | Inf |
insitu_reverse(x) | 1.000000 | 1.000000 | 6.684822 | NaN |
rev(x) | 6.170470 | 15.868918 | 1.000000 | Inf |
insitu_reverse(x) | 1.000000 | 1.000000 | 15.590267 | NaN |
rev(x) | 7.360748 | 17.015706 | 1.000000 | Inf |
insitu_reverse(x) | 1.000000 | 1.000000 | 15.858245 | NaN |
rev(x) | 6.505439 | 6.468984 | 1.000000 | Inf |
insitu_reverse(x) | 1.000000 | 1.000000 | 6.249604 | NaN |
res_abs <- bench::press(
N = N,
{
x <- runif(N)
bench::mark(
rev(x),
insitu_reverse(x),
check = TRUE,
relative = FALSE
)
}
)
res_abs %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
rev(x) | 2.54µs | 3.35µs | 279979.0743 | 0B |
insitu_reverse(x) | 641ns | 764ns | 1148403.6022 | 0B |
rev(x) | 3.02µs | 3.7µs | 231492.5363 | 1.27KB |
insitu_reverse(x) | 718ns | 820ns | 1110216.6455 | 0B |
rev(x) | 5.33µs | 7.75µs | 113639.8907 | 11.81KB |
insitu_reverse(x) | 1.03µs | 1.15µs | 823221.0911 | 0B |
rev(x) | 34.01µs | 79.71µs | 11979.8707 | 117.28KB |
insitu_reverse(x) | 4.53µs | 4.88µs | 190598.4239 | 0B |
rev(x) | 278.97µs | 716.12µs | 1380.1388 | 1.15MB |
insitu_reverse(x) | 39.46µs | 42.45µs | 21911.3579 | 0B |
rev(x) | 2.87ms | 3.5ms | 252.3226 | 11.44MB |
insitu_reverse(x) | 425.69µs | 525.97µs | 1746.0251 | 0B |
In-situ fill with random
insitu_fill_runif()
is analogous to runif()
but generates values in the current
vector rather than creating a new one.
x <- integer(10)
insitu_fill_runif(x, 10, 15)
x
[1] 14 10 10 14 15 13 11 10 10 11
Click to show/hide benchmark code & results
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Assign values into a vector
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# N = c(1e1, 1e2, 1e3, 1e4, 1e5, 1e6)
res_rel <- bench::press(
N = N,
{
x <- numeric(N)
bench::mark(
runif(x),
insitu_fill_runif(x, 0, 1),
insitu_fill_runif_fast(x, 0, 1),
check = FALSE,
relative = TRUE
)
}
)
res_rel %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
runif(x) | 1.892204 | 1.952124 | 1.000000 | Inf |
insitu_fill_runif(x, 0, 1) | 1.000000 | 1.000000 | 1.937939 | NaN |
insitu_fill_runif_fast(x, 0, 1) | 1.870067 | 1.896525 | 1.054534 | Inf |
runif(x) | 2.441160 | 2.689176 | 1.000000 | Inf |
insitu_fill_runif(x, 0, 1) | 1.000000 | 1.000000 | 2.702906 | NaN |
insitu_fill_runif_fast(x, 0, 1) | 1.209778 | 1.348808 | 2.093330 | Inf |
runif(x) | 8.089969 | 7.102734 | 1.000000 | Inf |
insitu_fill_runif(x, 0, 1) | 2.883208 | 2.530203 | 2.871414 | NaN |
insitu_fill_runif_fast(x, 0, 1) | 1.000000 | 1.000000 | 6.659101 | Inf |
runif(x) | 16.993506 | 19.090761 | 1.000000 | Inf |
insitu_fill_runif(x, 0, 1) | 5.584250 | 5.586271 | 3.393810 | NaN |
insitu_fill_runif_fast(x, 0, 1) | 1.000000 | 1.000000 | 18.507435 | Inf |
runif(x) | 19.036940 | 22.376697 | 1.000000 | Inf |
insitu_fill_runif(x, 0, 1) | 6.573531 | 6.956403 | 3.169354 | NaN |
insitu_fill_runif_fast(x, 0, 1) | 1.000000 | 1.000000 | 21.028264 | Inf |
runif(x) | 19.948139 | 20.726121 | 1.000000 | Inf |
insitu_fill_runif(x, 0, 1) | 6.616963 | 6.674905 | 3.027731 | NaN |
insitu_fill_runif_fast(x, 0, 1) | 1.000000 | 1.000000 | 19.864069 | Inf |
res_abs <- bench::press(
N = N,
{
x <- numeric(N)
bench::mark(
runif(x),
insitu_fill_runif(x, 0, 1),
insitu_fill_runif_fast(x, 0, 1),
check = FALSE,
relative = FALSE
)
}
)
res_abs %>%
select(expression, min, median, `itr/sec`, mem_alloc) %>%
knitr::kable()
expression | min | median | itr/sec | mem_alloc |
---|---|---|---|---|
runif(x) | 1.99µs | 2.59µs | 336636.38707 | 2.49KB |
insitu_fill_runif(x, 0, 1) | 1.07µs | 1.31µs | 656322.24018 | 0B |
insitu_fill_runif_fast(x, 0, 1) | 2.06µs | 2.75µs | 327837.27244 | 2.49KB |
runif(x) | 4.46µs | 5.26µs | 177614.21164 | 3.32KB |
insitu_fill_runif(x, 0, 1) | 1.84µs | 2.06µs | 439719.78282 | 0B |
insitu_fill_runif_fast(x, 0, 1) | 2.2µs | 3.02µs | 295293.68017 | 2.49KB |
runif(x) | 28.69µs | 30.94µs | 30566.18629 | 10.35KB |
insitu_fill_runif(x, 0, 1) | 10.06µs | 10.95µs | 88317.87574 | 0B |
insitu_fill_runif_fast(x, 0, 1) | 3.57µs | 4.4µs | 206912.05011 | 2.49KB |
runif(x) | 277.8µs | 348.6µs | 2823.69086 | 80.66KB |
insitu_fill_runif(x, 0, 1) | 95.31µs | 101.88µs | 9417.11075 | 0B |
insitu_fill_runif_fast(x, 0, 1) | 16.65µs | 18.25µs | 51459.46531 | 2.49KB |
runif(x) | 2.72ms | 3.26ms | 303.64721 | 783.79KB |
insitu_fill_runif(x, 0, 1) | 942.01µs | 1.03ms | 962.25305 | 0B |
insitu_fill_runif_fast(x, 0, 1) | 143.63µs | 148.54µs | 6491.03605 | 2.49KB |
runif(x) | 28.57ms | 32.02ms | 31.96567 | 7.63MB |
insitu_fill_runif(x, 0, 1) | 9.65ms | 10.38ms | 95.77602 | 0B |
insitu_fill_runif_fast(x, 0, 1) | 1.43ms | 1.49ms | 659.59949 | 2.49KB |
Acknowledgements
- R Core for developing and maintaining the language.
- CRAN maintainers, for patiently shepherding packages onto CRAN and maintaining the repository