-1

I have very little understanding of how Julia and R actually interprete code, but I have read that what makes Julia so fast is the multiple dispatch, which enables the prediction of types.

Now in R, S4 classes also have multiple dispatch, so my question is:

Could R be made as fast as Julia when everything was written with S4 classes?

And if not: What hinders R from being as fast as Julia?

Sebastian
  • 865
  • 5
  • 13
  • 4
    A1: "no". A2: A *lot*. https://ucidatascienceinitiative.github.io/IntroToJulia/Html/WhyJulia is useful. For the record, S4 dispatch is *slow*; writing everything in R in S4 would probably slow it down, not speed it up. – Ben Bolker Oct 01 '20 at 15:09
  • 1
    To add to that, Julia uses _just-in-time_ (JIT) compilation to _native_ code. That means it is actually closer to a language like C, which is (to a first approximation) what you see in performance benchmarks. Dispatching has nothing to do with either. – Dirk Eddelbuettel Oct 01 '20 at 16:42
  • I would say that this question should be re-opend. It is not opinion based because there exists a detailed technical explanation what causes than one language runs faster than other and moreover this question can be usefull for others to understand technical differences between languages. – Przemyslaw Szufel Oct 01 '20 at 22:54

1 Answers1

5

R is an interpreted programming language - see https://cran.r-project.org/doc/FAQ/R-FAQ.html#What-is-R_003f. Hence you have an interpreter that interprets and executes subsequent lines as the code runs. The libraries in R that have good performance are simply written in C - see for an example the src folder in the excellent data-tables libraries: https://github.com/Rdatatable/data.table

On the other hand Julia is a compiled language (and in the same dynamic and using multiple dispatch). Julia uses a LLVM compiler system to produce assembly from any piece of code before it gets executed. Consider for an example this Julia function:

f(x,y) = x < y ? 2x : 5;

When Julia executes it for the first time it gets an assembly code and actually if you want you can see it:

julia> code_native(f, (Int, Int))
        .text
; ┌ @ REPL[8]:1 within `f'
        pushq   %rbp
        movq    %rsp, %rbp
; │┌ @ int.jl:82 within `<'
        cmpq    %rdx, %rcx
; │└
        jge     L17
; │┌ @ int.jl:87 within `*'
        addq    %rcx, %rcx
; │└
        movq    %rcx, %rax
        popq    %rbp
        retq
L17:
        movl    $5, %eax
        popq    %rbp
        retq
        nopl    (%rax,%rax)
; └

This is a set of instructions directly understood by your CPU - no interpreter is involved. Should you decide to write this function in e.g. C and compile it you could expect very similar assembly lines.

Finally, note that this code is type specific - If you try code_native(f, (Int, Float64)) (so with different types) - you will get a totally different piece of assembly (try yourself!).

Hence the nature of interpreted and compiled languages is very different and R can only be fast when using external libraries written in C (or other compiled language).

Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62