Merge importFrom() calls to avoid loadNamespace() performance hit#1892
Merge importFrom() calls to avoid loadNamespace() performance hit#1892lionel- wants to merge 8 commits into
importFrom() calls to avoid loadNamespace() performance hit#1892Conversation
hadley
left a comment
There was a problem hiding this comment.
That's a pretty big performance hit!
I wonder if another approach would be to "compile" the NAMESPACE during the build process.
|
|
||
| lines <- c(namespace_imports(base_path), namespace_exports(NAMESPACE)) | ||
| results <- c(made_by("#"), sort_c(unique(trimws(lines)))) | ||
| results <- c(made_by("#"), merge_imports_from(sort_c(unique(trimws(lines))))) |
There was a problem hiding this comment.
Is there a reason you tackled this here instead of creating a richer representation of NAMESPACE files so we can just generate directly?
There was a problem hiding this comment.
It seemed simpler at first, until I hit the raw-namespace edge cases. I'll take another look.
There was a problem hiding this comment.
The other approach would be to parse the file since it's valid R code
|
One small behaviour change worth noting (probably acceptable): an import declared via both #' @importFrom stats median
#' @rawNamespace importFrom(stats,median)
NULL
#> main: "importFrom(stats,median)"
#> PR: "importFrom(stats,median)" "importFrom(stats,median)"Narrow (requires the same import both ways with matching formatting), but it does emit a duplicate directive. Easy to dedup the merged blocks against |
|
@kevinushey I think it's fine to basically ignore the contents of @lionel- I played around with a parsing based approach but ultimately didn't like. Instead I've added a minimally richer representation to the namespace data structure. I also changed the style to emit the package name on the first line which I think makes it clearer that the first argument is special. (This does not match our code style, but I think it's ok here since the |
I noticed that writing many
importFrom()lines to a NAMESPACE file causes a linear performance hit inloadNamespace()(values in ms):importFrom()singleimportFrom()manyexport()S3method()internalS3method()foreignloadNamespace()is complicated and fixing it upstream would be non-trivial. One approach that would work would be to coalesce contiguous runs of imports from the same package, which would fix the issue with Roxygen (since its generated namespace file is sorted) but not necessarily with manually written files.Even if it were fixed upstream, it's probably worth avoiding the perf hit on older R versions, so I thought we'd go ahead and merge the import calls in our namespace file generation.