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

Faster alternative to Sys.info() in digest() #137

Closed
wlandau opened this issue Dec 4, 2019 · 8 comments
Closed

Faster alternative to Sys.info() in digest() #137

wlandau opened this issue Dec 4, 2019 · 8 comments

Comments

@wlandau
Copy link
Contributor

wlandau commented Dec 4, 2019

I develop packages that call digest() repeatedly on small data. For use cases like these, the time spent on Sys.info() is often noticeable.

library(digest)
library(fs)
library(profile)
library(withr)

profile <- function(plan) {
  local_dir(dir_create(tempfile()))
  replicate(1e4, digest(letters, algo = "murmur32"))
  rprof <- "prof.rprof"
  pprof <- "prof.pprof"
  Rprof(filename = rprof)
  replicate(1e4, digest(letters, algo = "murmur32"))
  Rprof(NULL)
  data <- read_rprof(rprof)
  write_pprof(data, pprof)
  vis_pprof(pprof)
}

vis_pprof <- function(path, host = "localhost", port = NULL) {
  server <- sprintf("%s:%s", host, port %||% random_port())
  message("local pprof server: http://", server)
  args <- c("-http", server, path)
  if (on_windows()) {
    shell(paste(c("pprof", args), collapse = " "))
  } else {
    system2(jointprof::find_pprof(), args)
  }
}

random_port <- function(from = 49152L, to = 65355L) {
  sample(seq.int(from = from, to = to, by = 1L), size = 1L)
}

on_windows <- function() {
  tolower(Sys.info()["sysname"]) == "windows"
}

`%||%` <- function(x, y) {
  if (is.null(x) || length(x) <= 0) {
    y
  } else {
    x
  }
}

profile()

windows

Instead of

isWindows <- Sys.info()[["sysname"]] == "Windows"

would you be open to this?

isWindows <- .Platform$OS.type == "windows"

It looks much faster.

> microbenchmark::microbenchmark(a = .Platform$OS.type, b = Sys.info()[["sysname"]])
Unit: nanoseconds
 expr   min    lq  mean median    uq    max neval
    a   100   150   530    300   900   2900   100
    b 46700 49500 59365  50500 63250 168600   100

I would have just submitted a PR, but I need to jump through a couple hoops at my company first.

@eddelbuettel
Copy link
Owner

Good for the hoops :) I prefer talking before blindly jumping into PR.

What you suggest sounds fine. Givem that the platform one runs on rarely changes, we could also check once and only once at load, and the just retrieve a bool from a per-package env. Even cheaper? Worth it? Or not?

@eddelbuettel
Copy link
Owner

Also, instead of

isWindows <- .Platform$OS.type

presumably a comparison of that value against a known truth, no?

@wlandau
Copy link
Contributor Author

wlandau commented Dec 4, 2019

presumably a comparison of that value against a known truth, no?

Yes. I just fixed the typo.

@wlandau
Copy link
Contributor Author

wlandau commented Dec 4, 2019

What you suggest sounds fine. Givem that the platform one runs on rarely changes, we could also check once and only once at load, and the just retrieve a bool from a per-package env. Even cheaper? Worth it? Or not?

I like that idea. The speedup might be small compared to the rest of digest(), but per-package envs are straightforward to implement.

library(digest)
library(microbenchmark)
env <- new.env(parent = emptyenv())
env$is_windows <- TRUE
microbenchmark(
  env = env$is_windows,
  cmp = .Platform$OS.type == "windows",
  digest = digest(NULL)
)
#> Unit: nanoseconds
#>    expr   min    lq     mean  median      uq    max neval
#>     env   167   186   335.86   285.0   475.5   1377   100
#>     cmp   275   305   578.61   542.0   790.5   4228   100
#>  digest 69038 69970 75483.77 70550.5 71198.5 476413   100

Created on 2019-12-03 by the reprex package (v0.3.0)

@eddelbuettel
Copy link
Owner

eddelbuettel commented Dec 4, 2019

Yes. I have been using them for many years too; rpushbullet comes to mind, probably others too. I can take care of it, or if feel like it, can welcome a PR.

@wlandau
Copy link
Contributor Author

wlandau commented Dec 4, 2019

Thanks, Dirk. Since you are willing, I will leave the implementation to you. If you change your mind, please let me know and I will submit a PR.

@eddelbuettel
Copy link
Owner

I'll put it in a branch and let you review / test. Cool?

@wlandau
Copy link
Contributor Author

wlandau commented Dec 4, 2019

Sounds great.

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

No branches or pull requests

2 participants