From 5c4d7bb39bd6a59fe5f45b9e7fb3572c9c227580 Mon Sep 17 00:00:00 2001 From: Andrew Christianson Date: Tue, 7 Aug 2018 16:18:58 -0700 Subject: [PATCH] Use .get_cached_default_environment() from jedi In some situations, pyls can call Document.sys_path _very_ frequently. That method calls jedi.api.environment.get_default_environment(), which can call jedi.api.environment.find_system_pythons(). On systems with pyenv and many python versions installed, this can be expensive, as jedi._compatibilty.which returns a shim path for python major version. Each found version spawns a subprocess to check the specific version of the python found at the path (via creation of a jedi Environment). However, if it's only found the pyenv shim, when a subprocess is spawned, the shim fails to find the version, and pyenv spends significant time looking for the requested command in other installed pythons. Calling .get_cached_default_environment insures jedi goes through the above process no more than once per 10 minutes per instance of pyls. Even on systems without pyenv, calling get_default_environment() directly results in at least one subprocess invocation, and a new jedi Environment object for each invocation. As Document.sys_path can be called as often as once per keypress (depending on the client, though this seems to be the case for lsp-mode) reducing work on that path provides noticeable improvement in performance. --- pyls/workspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyls/workspace.py b/pyls/workspace.py index c731f670..eaebc12d 100644 --- a/pyls/workspace.py +++ b/pyls/workspace.py @@ -218,7 +218,7 @@ def sys_path(self): path = list(self._extra_sys_path) # TODO(gatesn): #339 - make better use of jedi environments, they seem pretty powerful - environment = jedi.api.environment.get_default_environment() + environment = jedi.api.environment.get_cached_default_environment() path.extend(environment.get_sys_path()) return path