jlview provides zero-copy R views of Julia-owned arrays using R’s ALTREP (Alternative Representations) framework. Instead of copying data between Julia and R, jlview returns lightweight R vectors that point directly into Julia’s memory.
| Latency | R Memory | |
|---|---|---|
| jlview (zero-copy) | 38 ms | 0 MB |
| copy (collect) | 2.7 s | 9.3 GB |
| Improvement | 72× | 100% savings |
Benchmark: 50K × 25K Float64 matrix (9.3 GB)
# install.packages("remotes")
remotes::install_github("tanaylab/jlview")library(jlview)
JuliaCall::julia_setup()
# Create a Julia array
JuliaCall::julia_command("x = randn(10000, 1000)")
# Zero-copy view — R sees Julia's memory directly
m <- jlview(JuliaCall::julia_eval("x"))
dim(m) # [1] 10000 1000
sum(m) # works natively, no data copied
# Named arrays are supported
JuliaCall::julia_command("using NamedArrays")
JuliaCall::julia_command("named = NamedArray(randn(3), [\"a\", \"b\", \"c\"])")
v <- jlview_named_vector(JuliaCall::julia_eval("named"))
v["a"] # access by name, still zero-copy
# Sparse matrices (zero-copy values, shifted indices)
JuliaCall::julia_command("using SparseArrays")
JuliaCall::julia_command("sp = sprand(1000, 500, 0.01)")
s <- jlview_sparse(JuliaCall::julia_eval("sp"))
class(s) # "dgCMatrix"
# Explicit release to free Julia memory early
jlview_release(m)dgCMatrix with
zero-copy values (nzval) and shifted indicesparallel::mclapply() (PID-guarded finalizers)saveRDS()/readRDS() work correctly
(materializes on save)| Julia type | R type | Method |
|---|---|---|
Array{Float64} |
numeric |
Direct zero-copy |
Array{Int32} |
integer |
Direct zero-copy |
Array{Float32} |
numeric |
Convert in Julia, then zero-copy |
Array{Int64} |
numeric |
Convert in Julia, then zero-copy |
Array{Int16} |
integer |
Convert in Julia, then zero-copy |
Array{UInt8} |
raw |
ALTREP RAWSXP zero-copy |
Array{Bool} |
logical |
Copy (layout incompatible) |
String[] |
character |
Copy (layout incompatible) |
jlview uses R’s ALTREP framework to create R vectors backed by Julia memory:
Dataptr returns Julia’s raw data pointerThe entire pin→ALTREP→finalizer path is implemented in C using
Julia’s C API (jl_call1), avoiding JuliaCall overhead and
ensuring safety during R’s garbage collection.