Make your R code run faster! rco
analyzes your code and applies
different optimization strategies that return an R code that runs
faster.
The rco
project, from its start to version 1.0.0, was made possible by
a Google Summer of Code 2019
project.
Thanks to the kind mentorship of Dr. Yihui Xie and Dr. Nicolás Wolovick.
rco
is currently only available as a GitHub package.
To install it run the following from an R console:
if (!require("remotes")) {
install.packages("remotes")
}
remotes::install_github("jcrodriguez1989/rco", dependencies = TRUE)
rco
can be used in three ways:
-
Using the RStudio Addins
-
Optimize active file
: Optimizes the file currently open in RStudio. It will apply the optimizers present inall_optimizers
. -
Optimize selection
: Optimizes the code currently highlited in the RStudio Source Pane. It will apply the optimizers present inall_optimizers
.
-
-
Using the
shiny
GUIs-
rco_gui("code_optimizer")
opens ashiny
interface in a browser. This GUI allows to easily optimize chunks of code. -
rco_gui("pkg_optimizer")
opens ashiny
interface in a browser. This GUI allows to easily optimize R packages that are hosted at CRAN or GitHub.
-
-
Using the R functions
- Optimize some
.R
code files
optimize_files(c("file_to_optimize_1.R", "file_to_optimize_2.R"))
- Optimize some code in a character vector
code <- paste( "code_to_optimize <- 8 ^ 8 * 1918", "cto <- code_to_optimize * 2", sep = "\n" ) optimize_text(code)
- Optimize all
.R
code files into a folder
optimize_folder("~/myfolder_to_optimize", recursive = FALSE)
- Optimize some
Suppose we have the following code:
code <- paste(
"# I want to know my age in seconds!",
"years_old <- 29",
"days_old <- 365 * years_old # leap years don't exist",
"hours_old <- 24 * days_old",
"seconds_old <- 60 * 60 * hours_old",
"",
"if (seconds_old > 10e6) {",
' print("Whoa! More than a million seconds old, what a wise man!")',
"} else {",
' print("Meh!")',
"}",
sep = "\n"
)
We can automatically optimize it by doing:
opt_code <- optimize_text(code, iterations = 1)
## Optimization number 1
## # I want to know my age in seconds!
## years_old <- 29
## days_old <- 365 * 29 # leap years don't exist
## hours_old <- 24 * days_old
## seconds_old <- 3600 * hours_old
##
## if (seconds_old > 10e6) {
## print("Whoa! More than a million seconds old, what a wise man!")
## } else {
## print("Meh!")
## }
After one optimization pass we can see that it has only propagated the
years_old
variable. Another pass:
opt_code <- optimize_text(opt_code, iterations = 1)
## Optimization number 1
## # I want to know my age in seconds!
## years_old <- 29
## days_old <- 10585 # leap years don't exist
## hours_old <- 24 * 10585
## seconds_old <- 3600 * hours_old
##
## if (seconds_old > 10e6) {
## print("Whoa! More than a million seconds old, what a wise man!")
## } else {
## print("Meh!")
## }
Now, it has folded the days_old
variable, and then propagated it.
Another pass:
opt_code <- optimize_text(opt_code, iterations = 1)
## Optimization number 1
## # I want to know my age in seconds!
## years_old <- 29
## days_old <- 10585 # leap years don't exist
## hours_old <- 254040
## seconds_old <- 3600 * 254040
##
## if (seconds_old > 10e6) {
## print("Whoa! More than a million seconds old, what a wise man!")
## } else {
## print("Meh!")
## }
It has folded the hours_old
variable, and then propagated it. Another
pass:
opt_code <- optimize_text(opt_code, iterations = 1)
## Optimization number 1
## # I want to know my age in seconds!
## years_old <- 29
## days_old <- 10585 # leap years don't exist
## hours_old <- 254040
## seconds_old <- 914544000
##
## if (914544000 > 10e6) {
## print("Whoa! More than a million seconds old, what a wise man!")
## } else {
## print("Meh!")
## }
It has folded the seconds_old
variable, and then propagated it into
the if
condition. Another pass:
opt_code <- optimize_text(opt_code, iterations = 1)
## Optimization number 1
## # I want to know my age in seconds!
## years_old <- 29
## days_old <- 10585 # leap years don't exist
## hours_old <- 254040
## seconds_old <- 914544000
##
## print("Whoa! More than a million seconds old, what a wise man!")
Now, it has folded the if
condition, and as it was TRUE
it just kept
its body, as testing the condition or the else
clause were dead code.
So, optimize_text
function has automatically detected constant
variables, constant foldable operations, and dead code. And returned an
optimized R code.
rco
is an open source package, and the contributions to the
development of the library are more than welcome. Please see our
CONTRIBUTING.md
file and “Contributing an
Optimizer”
article for detailed guidelines of how to contribute.
Please note that the ‘rco’ project is released with a Contributor Code of Conduct.
By contributing to this project, you agree to abide by its terms.