library(magrittr)
## Version 1 (Pipes)
# Convert a vector of integer to vector of strings of n binary digits
old_old_int_to_n_bits <- function(xs, n = 16, start = 1) {
vapply(xs, old_old_int_to_n_bits_one, FUN.VALUE = character(1),
n = n, start = start, USE.NAMES = FALSE)
}
# Convert an integer to a string of n binary digits
old_old_int_to_n_bits_one <- function(x, n = 16, start = 1) {
sequence <- seq(n, start, by = -1)
bits <- x %>% intToBits() %>% as.integer()
bits[sequence] %>% paste0(collapse = "")
}
## Version 2 (No pipes)
# Improvement of slower version
old_int_to_n_bits <- function(xs, n = 16, start = 1) {
vapply(xs, old_int_to_n_bits_one, FUN.VALUE = character(1),
n = n, start = start, USE.NAMES = FALSE)
}
# Convert an integer to a string of n binary digits
old_int_to_n_bits_one <- function(x, n = 16, start = 1) {
# I used pipes here before but those had a huge hit on performance for the
# problem with 40,000,000 numbers to compare
sequence <- seq(n, start, by = -1)
bits <- as.integer(intToBits(x))
paste0(bits[sequence], collapse = "")
}
## Version 3 (Convert numbers en masse)
int_to_n_bits <- function(xs, n = 16, start = 1) {
indices <- seq_len(length(xs))
# intToBits(xs) returns 32 bits for each number of xs and each bit has a
# leading zero like 01 00 00 00. The item on the left is the smallest digit.
#
# as.integer() will remove the leading zeros.
#
# The rep() lines produces 1 repeated 32 times followed by 2 repeated 32
# times, etc. Splitting on these values will get us a list where each element
# in the list has the binary digits for each number.
bits <- split(as.integer(intToBits(xs)), rep(indices, each = 32))
# Here we convert the vectors of binary digits into strings. Using `n:start`
# will reverse the digits so the smallest digit is on the right.
vapply(bits, function(x) paste0(x[n:start], collapse = ""),
character(1), USE.NAMES = FALSE)
}
xs <- 1:1000L
microbenchmark::microbenchmark(
version1 = old_old_int_to_n_bits(xs),
version2 = old_int_to_n_bits(xs),
version3 = int_to_n_bits(xs),
times = 100L)
## Unit: milliseconds
## expr min lq mean median uq max
## version1 336.42408 339.12989 344.52020 340.79864 342.52616 405.86759
## version2 38.84024 39.63414 40.30618 40.20242 40.68446 45.44770
## version3 11.92375 12.09872 12.47795 12.22601 12.52894 19.09137
## neval cld
## 100 c
## 100 b
## 100 a