Skip to content

Consider replacing shell-command-to-string invocations with direct call-process invocations #1044

Closed
@colonelpanic8

Description

@colonelpanic8

Projectile makes extensive use of the shell-command-to-string elisp function when it uses the 'alien indexing method. The advantage of this is, I presume, that the appropriate binary will automatically be detected based on the users shell configuration.

However, for people with non-trivial shell startup times there is a somewhat steep performance penalty to this approach. I have an extensive zsh configuration, but I have made an effort to keep it as lean as possible, and I still see a significant performance penalty to shell-command-to-string.

I used this measure-time macro to investigate this

(defmacro measure-time (&rest body)
  "Measure and return the running time of the code block."
  (declare (indent defun))
  (let ((start (make-symbol "start")))
    `(let ((,start (float-time)))
       ,@body
       (- (float-time) ,start))))

Unfortunately, because of the way that git works, we need to invoke the git-ls-files command directly. (supplying the ls-files argument doesnt work.

(measure-time
  (call-process "/usr/local/opt/git/libexec/git-core/git-ls-files" nil "git-ls-output" "-zco" "--exclude-standard")) => 0.02278304100036621
(measure-time
  (shell-command-to-string projectile-git-command)) => 0.5086848735809326

This is an order of magnitude difference, and because projectile actually invokes MULTIPLE shell commands for each emacs command, this penalty is paid several times.

I realize that rearchitechting this would be somewhat difficult, but would you be open to a change to use call-process when the path to git subcommands is explicitly specified?

Projectile version information

Projectile version: 0.13

Emacs version

E.g. 25.1

Operating system

OSX Yosemite

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions