Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R's byte compiler overhead #149

Open
dselivanov opened this issue Jun 8, 2020 · 2 comments
Open

R's byte compiler overhead #149

dselivanov opened this issue Jun 8, 2020 · 2 comments

Comments

@dselivanov
Copy link
Collaborator

dselivanov commented Jun 8, 2020

Issue #146 brought interesting discovery.

@s-u I actually haven't check the R benchmark code from #146. I was pretty sure that the main issue was due to fork overhead (which was somewhat aligned with my benchmarks here).

However I've run your code and indeed the fork overhead is very small. And that pointed me to the real source of why things are pretty slow when keep-alive is disabled: R's byte compiler. The "issue" here is that it seems compile .http.request and functions which are used inside it during every invocation. And since each request is handled in a fresh fork, it compiles it every time which adds significant overhead. I was suspecting this and tried to mitigate it here, but it seems it is not enough.

Consider following (pure Rserve) example:

calc_fib = function(n) {
  if (n < 0L) stop("n should be >= 0")
  if (n == 0L) return(0L)
  if (n == 1L || n == 2L) return(1L)
  x = rep(1L, n)
  for (i in 3L:n) x[[i]] = x[[i - 1]] + x[[i - 2]]
  x[[n]]
}

.http.request <- function(path, query, body, headers) {
  n = query[["n"]]
  n = as.integer(n)
  list(charToRaw(as.character(calc_fib(n))), "text/plain")
}

Rserve:::run.Rserve(http.port=8092)

Testing with disabled JIT and disabled keep-alive

R_ENABLE_JIT=0 Rscript bench.R
./apib -c 1 -d 1 -k 0 http://localhost:8092/fib?n=10

gives around 550 req/s

Testing with enabled JIT and disabled keep-alive

R_ENABLE_JIT=3 Rscript bench.R
./apib -c 1 -d 1 -k 0 http://localhost:8092/fib?n=10

gives around 25 req/s

@s-u do you have any ideas on how to mitigate this apart from disabling byte compiler? (I don't really have an idea on how R's byte compiler works)

@dselivanov dselivanov removed the Rserve label Jun 8, 2020
dselivanov added a commit that referenced this issue Jun 10, 2020
- disable jit within Rserve backend by default
- try to recursively byte-compile global env by default
@dselivanov
Copy link
Collaborator Author

Several discoveries here

Recent changes in 3516e89 led to noticeable speedup when keep-alive disabled / each request opens new connection: 8 req/s -> 105 req/s on fibonacci benchmark. Pure Rserve is about 550 req/s.

Fork overhead is ~1ms on my machine.

dselivanov added a commit that referenced this issue Jun 11, 2020
* disable jit

* related to #149:
- disable jit within Rserve backend by default
- try to recursively byte-compile global env by default

* add "add = TRUE" in "on.exit" call

* update docs and tests related to JIT
@dselivanov
Copy link
Collaborator Author

Another speed up to R6 classes - https://github.com/duncantl/R6CompileNew

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants