简体   繁体   中英

How to speed up startup of Powershell in the 4.0 environment?

I'm considering using Powershell scripts for triggers on our Perforce server. Unfortunately, even on our fast hardware it still takes 2 seconds for Powershell to start up. Now, this doesn't seem like much time unless you consider that 200 users are pounding the server constantly, and a trigger may (depending on conditions) cause a table lock while it runs, stalling out other related requests.

I'm looking for ways to reduce the startup time of Powershell. Things that I've found on Google:

  • Reduce the profile. This is a default installation, no profile customization, no PSCX, etc. so this doesn't help.
  • Run NGEN on Posh binaries. This is old advice for a V1 issue. We're on V2.
  • Keep it warm. Initial Posh startup is slow but later startups are fast. Also not helpful for us. On the server the warm start is 2 seconds and it's kept warm by frequent requests.
  • Don't use Powershell for this purpose. Well, I'm hoping to avoid that "solution"...

Does anyone have any other suggestions for cutting startup time? I'm not expecting a startup as fast as cmd.exe or a .NET command line app, but if I can get this to .5 seconds I think we'll be ok. Impossible?

UPDATE - it turns out this is a 4.0 issue. If I add a config file as described in another SO question the startup takes 2 seconds. If I leave it at its default, then startup is under a quarter second.

Then I thought..perhaps it's a 4.0 GAC issue. So I ran the script on the PowerShell Blog but it says all the assemblies are already ngen'd. I made sure that it is indeed using the 4.0 ngen as well.

So I'm left with two options:

  • Figure out why 4.0 is so much more expensive than 3.5.
  • Switch to the 3.5 framework where I do not need it and I do need the performance.

I'd love to solve the first but don't know where to start. Can anyone help?

Run NGEN on Posh binaries. This is old advice for a V1 issue. We're on V2.

I've been playing with this under V3, and I found out that some images were generated.

And it certainly feels like startup is now much faster. I'll know better after a reboot, as the first time is always the worst. The (my updated) script to do so with Win 7 is

$env:path = [Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()
[AppDomain]::CurrentDomain.GetAssemblies() | % {
  if (! $_.location) {continue}
  $Name = Split-Path $_.location -leaf
  Write-Host -ForegroundColor Yellow "NGENing : $Name"
  ngen install $_.location | % {"`t$_"}
}

Following an excellent answer to my question on Technet , I discovered a much easier way to trigger NGEN manually (since it seems it doesn't happen automatically on a clean install of Windows 8.1):

schtasks /Run /TN "\Microsoft\Windows\.NET Framework\.NET Framework NGEN v4.0.30319"
schtasks /Run /TN "\Microsoft\Windows\.NET Framework\.NET Framework NGEN v4.0.30319 64"

I'm afraid you're probably out of luck if you stick with the console host powershell.exe, unless you feel like writing an optimized script processor by hosting a runspace/runspacefactory in a custom console application - or a windows service - you roll yourself. You might shave a second off, but 0.5s startup for a .NET application is unlikely, especially if the servers are tight for memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM