JanDeDobbeleer / oh-my-posh

The most customisable and low-latency cross platform/shell prompt renderer
https://ohmyposh.dev
MIT License
17.41k stars 2.38k forks source link

Performance: Command Execution Slow in Git Repositories #873

Closed Balrrach closed 3 years ago

Balrrach commented 3 years ago

Prerequisites

Description

Hello. The program runs very smothly(almost instantaneously) when outside a git repository, but as soon as I enter a git repository(ir doesn't matter how big or small it is) it gets slow taking more than 300ms to execute on average wich is noticible. An example can be seen in the picture below: slow2

I have followed the steps described in the offitial page for the installation. I've been browsing the internet trying to look for a solution or verifying if this was normal or not but couldn't find an answer. Also, on the youtube videos I visited seemed didn't seem to be any kind of slowdowns when getting in a git repository.

I want to know if this is normal and if it is not I'd like to know how I could try to fix it. Thanks in advance!

lnu commented 3 years ago

Could you add your git version and your posh-git version(if used?)?

JanDeDobbeleer commented 3 years ago

To be clear, this is without status enabled? Can you share your config/theme?

Balrrach commented 3 years ago

Could you add your git version and your posh-git version(if used?)?

git version is 2.32.0.windows.2. posh-git version is 1.0.0. oh-my-posh version is 3.169.3.

To be clear, this is without status enabled? Can you share your config/theme?

I don´t know what you mean. I have default settings, I haven't created the config file. I currently have pure theme at the moment but the problem persist with all available default themes.

JanDeDobbeleer commented 3 years ago

@Balrrach OK, so pure has "display_status": true set so it will always fetch the status using git --no-optional-locks -c core.quotepath=false -c color.status=false status -unormal --short --branch. Can you check how long that command takes?

Normally, using a theme like avit should make it a lot faster as that one does not fetch git status, it parses the worktree contents.

amoldeshpande commented 3 years ago

as an interesting aside, I did a comparison with the posh version I have and the current one when we were discussing this in the closed bug:

https://github.com/JanDeDobbeleer/oh-my-posh/issues/305#issuecomment-889062888

my theme does have a git element, but the interesting thing is that there is a definite regression between the two versions.

I copied the git segment from the avit theme and it had no improvement in timing.

JanDeDobbeleer commented 3 years ago

I wonder which of the commands is causing the issue on Windows. So, the difference between the two is:

amoldeshpande commented 3 years ago

just measuring the two from powershell, the first takes 20-30ms while the second takes 50-52 ms. adding 40ms go overhead for a single process spawning still doesn't get me to 90ms vs 270ms

JanDeDobbeleer commented 3 years ago

I'll prepare some additional debug statements for this lovely segment. I truly don't like git for Windows 😅

Balrrach commented 3 years ago

Normally, using a theme like avit should make it a lot faster as that one does not fetch git status, it parses the worktree contents.

Problem persists with avit: imagen

I wonder which of the commands is causing the issue on Windows. So, the difference between the two is:

* `git branch --show-current`

* `git --no-optional-locks -c core.quotepath=false -c color.status=false status -unormal --short --branch` vs `git -c core.quotepath=false -c color.status=false status -unormal --short --branch`

This first screenshot is git --no-optional-locks -c core.quotepath=false -c color.status=false status -unormal --short --branch timing first in a not git directory and second in a git directory: imagen

This second screenshot is git branch --show-current timing first in a not git directory and second in a git directory: imagen

JanDeDobbeleer commented 3 years ago

@Balrrach when 3.171.0 is available, using Write-PoshDebug will log the calls to a file at ~/oh-my-posh.log. That one can be used to identify where the time is spent.

lnu commented 3 years ago

@JanDeDobbeleer I did a small try be replacing the call to g.getGitCommandOutput("remote", "get-url", upstream) by reading the .git config file directly and it saves 75ms on my side(on the ohmyposh repo). Going from +-280 ms to 205ms. Could be already an improvement.

I have to check if it works with worktree.

https://github.com/lnu/oh-my-posh/tree/perf/segment_git

JanDeDobbeleer commented 3 years ago

@lnu should work with a worktree tbh. Curious about the other's feedback here as well. Let's already do this.

lnu commented 3 years ago

@JanDeDobbeleer I tested and did some changes, tell me what you think

https://github.com/JanDeDobbeleer/oh-my-posh/pull/878

Balrrach commented 3 years ago

@Balrrach when 3.171.0 is available, using Write-PoshDebug will log the calls to a file at ~/oh-my-posh.log. That one can be used to identify where the time is spent.

This is the log:

2021/08/02 16:16:00 func: getArgs duration: 0s, args: 
2021/08/02 16:16:00 func: getShellName duration: 10.7239ms, args: 
2021/08/02 16:16:00 func: isRunningAsRoot duration: 0s, args: 
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getShellName duration: 0s, args: 
2021/08/02 16:16:00 func: getCurrentUser duration: 0s, args: 
2021/08/02 16:16:00 func: getHostName duration: 524.1µs, args: 
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: isRunningAsRoot duration: 0s, args: 
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: getArgs duration: 0s, args: 
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: getRuntimeGOOS duration: 0s, args: 
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: hasCommand duration: 524.2µs, args: git
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: hasParentFilePath duration: 25µs, args: .git
2021/08/02 16:16:00 func: getRuntimeGOOS duration: 0s, args: 
2021/08/02 16:16:00 func: runCommand duration: 297.6843ms, args: git.exe --no-optional-locks -c core.quotepath=false -c color.status=false status -unormal --short --branch
2021/08/02 16:16:00 func: hasFolder duration: 0s, args: C:\Users\balta\Documents\Configuration-Files\.git/rebase-merge
2021/08/02 16:16:00 func: hasFolder duration: 26.2µs, args: C:\Users\balta\Documents\Configuration-Files\.git/rebase-apply
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: hasFilesInDir duration: 0s, args: MERGE_MSG
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: hasFilesInDir duration: 0s, args: CHERRY_PICK_HEAD
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: hasFilesInDir duration: 0s, args: REVERT_HEAD
2021/08/02 16:16:00 func: getPathSeperator duration: 0s, args: 
2021/08/02 16:16:00 func: hasFilesInDir duration: 0s, args: sequencer/todo
2021/08/02 16:16:00 func: getFileContent duration: 506.9µs, args: C:\Users\balta\Documents\Configuration-Files\.git/logs/refs/stash
2021/08/02 16:16:00 func: getRuntimeGOOS duration: 0s, args: 
2021/08/02 16:16:00 func: runCommand duration: 44.1672ms, args: git.exe --no-optional-locks -c core.quotepath=false -c color.status=false remote get-url origin
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: executionTime duration: 0s, args: 
2021/08/02 16:16:00 func: getcwd duration: 0s, args: 
2021/08/02 16:16:00 func: lastErrorCode duration: 0s, args: 
2021/08/02 16:16:00 func: lastErrorCode duration: 0s, args: 
2021/08/02 16:16:00 func: lastErrorCode duration: 0s, args: 

Time is mainly spent in git.exe --no-optional-locks -c core.quotepath=false -c color.status=false status -unormal --short --branch but it doesn't make any sense because when I measure the time I get: imagen

amoldeshpande commented 3 years ago

Is there a newer go runtime involved by any chance compared to 3.79 ?

go is pathologically bad when it comes to Windows and I wouldn't be surprised if there was a regression.

lnu commented 3 years ago

If I try the measure-command on my side, I get more or less the same result(except the 30ms overhead from go).

omp built with: image

JanDeDobbeleer commented 3 years ago

@amoldeshpande there is indeed a newer version since that version (we moved to 1.16). I created a change that made quite the impact on my machine (went from 1400ms to 300ms).

JanDeDobbeleer commented 3 years ago

closed due to no response

github-actions[bot] commented 7 months ago

This issue has been automatically locked since there has not been any recent activity (i.e. last half year) after it was closed. It helps our maintainers focus on the active issues. If you have found a problem that seems similar, please open a discussion first, complete the body with all the details necessary to reproduce, and mention this issue as reference.