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:
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:
I'd love to solve the first but don't know where to start. Can anyone help?
Click Start, type PowerShell, and then click Windows PowerShell. From the Start menu, click Start, click All Programs, click Accessories, click the Windows PowerShell folder, and then click Windows PowerShell.
The PowerShell Start-Process cmdlet opens an executable file — such as a script file. If it's not an executable file; it starts the program associated with the file.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With