Microsimulation modeling is computationally intensive.
"R is not necessarily an ideal language for computationally intensive processes."[1]
For high computational performance, C and Fortran are the gold standard.
Often, the core of the R code is re-written in C++ and seeminglessly integrated into R functions/packages through the Rcpp package.
However, low-level programming languages, such as C/C++ and Fortran, is an unfamiliar endeavor for many R programmers.
Is there a programming language like R that can provide high computational performance like C++?
R | Julia | C++ | |
---|---|---|---|
Compilation | None (interpreted) | Just-In-Time (JIT) | Ahead-Of-Time (AOT) |
Type system | Dyanmic | Dynamic | Static |
# generate values from Uniform(0,1)
x = rand(100000)
# define a function that computes the average of a vector of numbers
function compute_mean(α)
sum(α)/length(α)
end
# computes the wall-clock time
@time compute_mean(x);
@time compute_mean(x);
0.014783 seconds (3.74 k allocations: 177.685 KiB) 0.000078 seconds (1 allocation: 16 bytes)
# type annotation example
# :: is used to declare type
@show (1+1)::Int
@show (1+1.0)
@show (1+1.0)::Int
(1 + 1)::Int = 2 1 + 1.0 = 2.0
TypeError: in typeassert, expected Int64, got a value of type Float64 Stacktrace: [1] top-level scope at show.jl:641 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091
# generate values from Uniform(0,1)
x = rand(100000)
# define a function that computes the average of a vector of numbers
function compute_mean(α)
sum(α)/length(α)
end
# @time is a macro that computes the wall-clock time
@time compute_mean(x);
@time compute_mean(x);
# You can declare the type of the input
function compute_mean_typed(α::Vector{Float64})
sum(α)/length(α)
end
@time compute_mean_typed(x);
0.022176 seconds (3.74 k allocations: 177.685 KiB) 0.000087 seconds (1 allocation: 16 bytes) 0.000070 seconds
using Distributions
# 50% quantile
# "." is equivalent to broadcasting in Python or apply in R
# quantile is also used to compute the quantile of a vector of numbers
@show quantile.([Uniform(0,1),Normal(0,1),Poisson(1),rand(100)],0.5)
# quantile has 66 different methods
quantile
quantile.([Uniform(0, 1), Normal(0, 1), Poisson(1), rand(100)], 0.5) = Real[0.5, 0.0, 1, 0.45467727634503763]
quantile (generic function with 66 methods)
# input is a vector of float
function compute_mean_multiple(α::Vector{Float64})
sum(α)/length(α)
end
# same function name but now the input is a vector of numeric strings
function compute_mean_multiple(α::Vector{String})
α = parse.(Float64,α)
sum(α)/length(α)
end
@show methods(compute_mean_multiple);
# sample from Unif(0,1)
x=rand(10)
# convert those numeric values into numeric strings
s_x = string.(x)
# check whether the outputs are equal
println(compute_mean_multiple(x) == compute_mean_multiple(s_x))
methods(compute_mean_multiple) = # 2 methods for generic function "compute_mean_multiple": [1] compute_mean_multiple(α::Array{String,1}) in Main at In[7]:7 [2] compute_mean_multiple(α::Array{Float64,1}) in Main at In[7]:2 true