kelleyma49 / PSFzf

A PowerShell wrapper around the fuzzy finder fzf
MIT License
795 stars 36 forks source link

Slow Start #23

Closed Swoorup closed 4 years ago

Swoorup commented 5 years ago

Adding this plugin hogs powershell start time.

kelleyma49 commented 5 years ago

Indeed, it takes about 25% of the startup time (1 second of my 3.7 second start time). I'll see what I can do about decreasing this.

lzybkr commented 5 years ago

I'll bet Add-Type is a big part of the startup time.

You could maybe do that in the background, but converting the script to a binary module would be a bigger win from a performance perspective. It already makes heavy use of .Net and might benefit from using C# events instead of PowerShell events.

kelleyma49 commented 5 years ago

@lzybkr: thank you for your help. I had some time to throw some Measure-Commands around the module code. The total time to load PSFzf is around 0.88 seconds on my Dell XPS 15. The Add-Type only takes ~ 0.18 seconds. Loading the helper functions script takes ~0.41 seconds.

It looks as though the Get-Command calls can take a significantly long time. I tested this by redefining Get-Command in PSFzf.Functions.ps1 to return $true and that brought down the total time to ~ 0.46 seconds. I tried a couple of things to make the Get-Command calls faster: 1) call Get-Command once with all of the commands we trying to find; 2) specify the -CommandType parameter for Applications, Functions, and Aliases; and 3) set $PSModuleAutoLoadingPreference='None', but none of these seemed to significantly decrease the load time.

I can't see any easy ways to decrease load time with breaking functionality. As you mentioned, moving the entire module to C# might help in load time.

lzybkr commented 5 years ago

@kelleyma49 - Add-Type can be much slower if the C# compiler hasn't been loaded. There is a compiler server running in the background to hide the startup costs of loading the compiler so you only pay that overhead once, or no more than once every 15 minutes (I think the process exits if it's inactive.)

Also - Add-Type keeps a cache so it doesn't recompile the same code more than once, so if you repeatedly measure via Remove-Module and Import-Module, you'll get very different results than loading in new process.

kelleyma49 commented 5 years ago

@lzybkr Ah, I understand now. Thanks for the clarification!

kelleyma49 commented 5 years ago

In the latest version (https://www.powershellgallery.com/packages/PSFzf/1.1.22) I've moved the ReverseLineReader into a binary module. @Swoorup, give it a try to see if your startup times have decreased.

farzadmf commented 5 years ago

Any updates on this issue? I'm using 1.1.23, and it's still slow. I noticed that on PowerShell Core, it's much faster

r-darwish commented 4 years ago

I think that for start we can get rid of the Get-Command for Search-Everything, Get-ZLocation and git. If it's more expensive then just defining the 3 functions then I think it's best just to defined them.

The Get-Command for Get-Frecents is more complicated because it has an else if clause. There are two options here:

  1. Stop supporting Get-Frecents which seems to be unmaintained since 2016 (It also doesn't have any link to a source repository).
  2. Define a single function that decides that to do in the function body.

These changes saved me ~200 ms.

SRGOM commented 4 years ago

For me, in PS7, it's literally half a second without this module vs 4 secs with it!

I don't know what it means but "not declaring your exports in the manifest" would cause PS to read your entire code causing it to lag. Are you doing that already?

Praful commented 4 years ago

[Update: after putting laptop to sleep and returning later, the startup time is 1.4-1.9 secs, which is comparable to PS6]

For me, in PS7, it's literally half a second without this module vs 4 secs with it!

I don't know what it means but "not declaring your exports in the manifest" would cause PS to read your entire code causing it to lag. Are you doing that already?

I'm finding the same on PS7 - 0.6 seconds without, 6 secs with.

$error doesn't return anything. I'm using PSFzf v1.2.0 on Windows 10 1909.

giggio commented 4 years ago

For me it takes 3.5s in Windows PowerShell and 3s in Posh7.

kelleyma49 commented 4 years ago

Try this version to see if it's any faster: https://www.powershellgallery.com/packages/PSFzf/1.2.5-alpha

Praful commented 4 years ago

Thanks for the new release. My PS 7 startup times were 1.4-1.9s when I posted on 9 April.

I redid tests and was getting 1.5-1.6 after initial loads.

With the new release (1.2.5-alpha), I'm getting about 1.41-1.51s.

I'm using PS 7 in ConEmu. CMD and Windows Terminal are about 100ms faster.

Note for installation: I had to use the -Force, that is:

Install-Module -Name PSFzf -AllowPrerelease -Force
kelleyma49 commented 4 years ago

@Praful that's a bummer it's not more than that. However, I just made some more changes that shaved off a little more than 1/2 second in my test case (my load time went from ~1.6 seconds to ~1 second. You can get the latest Prerelease here to test it out: https://www.powershellgallery.com/packages/PSFzf/1.2.6-alpha.

⚠Note that this is a breaking change as PSFzf no longer automatically enables the aliases. You can enable all aliases using 1 of 2 methods:

Give it a try and let me know the results. I don't know what I can do beyond this, so I probably won't continue to work on this issue unless I'm fixing bugs. I'm always open to pull requests.

Praful commented 4 years ago

@kelleyma49 Great news: 1.2.6-alpha has reduced startup time to a very respectable 550-650ms! Thank you.

rgwood commented 4 years ago

This is much faster for me in 2.0! My load time has gone from ~1.5s to 800-900ms. Great improvement, thank you @kelleyma49

kelleyma49 commented 4 years ago

I'll close this out as it looks like start time is acceptable.