Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign upImprove powershell startup time #8341
Conversation
daxian-dbw
requested review from
lzybkr,
TravisEz13,
SteveL-MSFT,
adityapatwardhan,
PaulHigin and
iSazonov
Nov 27, 2018
daxian-dbw
requested review from
anmenaga,
BrucePay and
JamesWTruher
as
code owners
Nov 27, 2018
This comment has been minimized.
This comment has been minimized.
Do you continue in the PR?
I don't see Microsoft.ApplicationInsights.dll in the table - no jitting? I searched "Insights" in our code base and have questions:
If
having
I think that an ordinary user computer is 2 physical cores and it would be correct to limit the test to two physical cores. (This may be related to tied compilation) |
This comment has been minimized.
This comment has been minimized.
|
I restarted CI-MacOs. |
iSazonov
reviewed
Nov 27, 2018
This comment has been minimized.
This comment has been minimized.
|
@iSazonov Reply to your comment here:
No, that will be in a new PR. The planned work are as follows:
After the change, no IL code needs to be jitted for this dll at startup time.
Yes we do. Type conversion depends on the type catalog. Not all .NET Core assemblies shipped with PS Core are loaded at startup. Today, user can use a type even it's from an assembly that is not loaded yet, because powershell knows which assembly the type is from by looking in the type catalog. Without it, the user needs to know which assembly the type is in, and then load the assembly first before using the type. The type catalog is also used in tab completion, so that powershell can tab complete types that are not loaded yet.
ApplicationInsight telemetry is done in console.dll at startup, as long as the user hasn't opted out.
The work that is done in this PR are based on the analysis of Reference Set and Jitting time. Some ad-hoc analysis on the static members might be useful, but I think our efforts should be guided by the measurement data, so our time can be spent on things that matters most.
The reason to change
There is no interference from other pwsh processes when running the tests.
The baseline is the same, and here we care most about the percentage of improvement instead of the actual startup time. As for multi-core background jitting, with changes in this PR, only |
This comment has been minimized.
This comment has been minimized.
|
The macOS failure appears to be a test code issue:
(note that |
This comment has been minimized.
This comment has been minimized.
|
For the logging test that was failing in previous macOS CI, it's caused by removing |
This comment has been minimized.
This comment has been minimized.
But the dll is loaded at startup. Only "Type conversion depends on the type catalog" prevents us from removing the dll from TypeCatalog?
I understand. My request is - Does the telemetry delay startup or no? If yes we could postpone the telemetry call and loading the dll.
I think these outlies is important to investigate in the startup context. Outlier is unexpected delay. Why we see unexpected delay in the tests? |
This comment has been minimized.
This comment has been minimized.
Not sure what you mean by "But the dll is loaded at startup". Most of the assemblies included in the type catalog file are not loaded at startup. Even for the dlls that are loaded at startup, type resolution would be much faster for a type from those dlls because we can avoid the effort to search types from all loaded assemblies to find the one.
The telemetry definitely play a role in the startup time, but I don't know how much after crossgen'ing the dll because I'm not able to analyze the stack info in PerfView/WPA with crossgen'ed assemblies yet.
Every run of the test starts those processes many times for measurement, including the warm-up. Not every test has outliers in it. I think it's more related to the factors that is out of our control, such as the OS. BTW, I replaced the detailed test record with a most recent run (after |
PaulHigin
requested changes
Nov 28, 2018
PaulHigin
requested changes
Nov 28, 2018
This comment has been minimized.
This comment has been minimized.
|
@lzybkr @PaulHigin @TravisEz13 Can you please look at the new changes to Major change is on how we decide to skip AMSI/malicious code scan. The previous way to check for skipping An attacker can put arbitrary content in a The skip-scan condition is changed to:
The API |
This comment has been minimized.
This comment has been minimized.
|
We have many comments in the PR that is a problem for GitHub web interface. If security concerns have been fixed we could merge and continue with hash function in follow PR. |
iSazonov
added
the
CL-CodeCleanup
label
Nov 29, 2018
PaulHigin
approved these changes
Nov 29, 2018
|
LTGM. Just minor comments. |
This comment has been minimized.
This comment has been minimized.
|
@daxian-dbw Seems you could merge. |
This comment has been minimized.
This comment has been minimized.
|
@lzybkr Would you like to take another look before I merge? |
lzybkr
reviewed
Nov 30, 2018
| @@ -221,6 +226,40 @@ private void PerformSecurityChecks() | |||
| { | |||
| HasSuspiciousContent = true; | |||
| } | |||
|
|
|||
| // We can skip code scan if the ScriptBlockAst is from a .psd1 file and it's in fact a safe HashtableAst. | |||
| bool CanSkipCodeScan() | |||
This comment has been minimized.
This comment has been minimized.
lzybkr
Nov 30, 2018
Member
The comment and code do not match - it is possible to call this method where the filename is not a psd1 file.
This code is also not future proof - it would be easy to miss the need for adding code here when the ast is enhanced. I don't have a simple suggestion on how to fix though.
What you really want is structural equivalence to an oracle, ignoring the children of the hashtable, then calling IsAstSafe, but I can't think of a fast way to implement that.
This comment has been minimized.
This comment has been minimized.
daxian-dbw
Nov 30, 2018
Author
Member
Updated the local function name and comment to make them match.
I agree the code is not future proof ... I cannot think of a better solution. I added a NOTE comment in the local function to call it out.
daxian-dbw
force-pushed the
daxian-dbw:perf
branch
from
d56469a
to
202535c
Nov 30, 2018
daxian-dbw
added some commits
Nov 26, 2018
daxian-dbw
force-pushed the
daxian-dbw:perf
branch
from
202535c
to
51733c4
Nov 30, 2018
This comment has been minimized.
This comment has been minimized.
|
Attempt to address comments + rebased to resolve the conflict in |
This comment has been minimized.
This comment has been minimized.
|
The failed test is most likely caused by #8346. It's a feature-level test, but the commits in that PR don't have the Here is the failure:
|
daxian-dbw
merged commit a11810b
into
PowerShell:master
Dec 2, 2018
5 of 6 checks passed
daxian-dbw
deleted the
daxian-dbw:perf
branch
Dec 2, 2018
This comment has been minimized.
This comment has been minimized.
|
Did we lose a bit of performance with latest commits? |
This comment has been minimized.
This comment has been minimized.
|
Yeah, it looks so to me. The average startup time improvement compared with PS Core 6.1 drops to It's the price for security, I guess :/ But I think we can possibly further improve it by having an internal overload of |
TravisEz13
referenced this pull request
Dec 4, 2018
Closed
Create module analysis cache in containers #61
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
|
Can you elaborate a bit on the |
This comment has been minimized.
This comment has been minimized.
|
@daxian-dbw See here for the discussion on that: #8120 |
daxian-dbw commentedNov 27, 2018
•
edited
PR Summary
With this PR, the startup time of
pwshgets about24.5%improvement on average comparing with the PS Core 6.1.0 official release. The following is an example measurement result by usingBenchmarkDotNet v0.11.2(the detailed information about this measurement result can be found at the end):Detailed Changes
SecuritySupport.IsProductBinaryand unnecessary AMSI/suspicious code scan at startup time for a regular sessionCompiledScriptBlockData.IsProductCodeto avoid unnecessary calls toIsProductBinary, which attempts to retrieve catalog signature of the target file.PerformSecurityChecksto skip AMSI and suspicious code scan for the.psd1file that contains a safeHashtableAstonly.ReadOnlyHashSetinstead ofImmutableHashSetso that we can avoid loading theSystem.Collections.Immutable.dllcompletely.SHA1withCRC32when generating module analysis cache file nameSystem.Security.Cryptography.Algorithms.dllat startupConvertFrom-SddlStringto C# to remove theUtility.psm1file.Microsoft.ApplicationInsights.dlland enable tiered compilation191.6mscomparing with24.7msfor Windows PowerShell.Microsoft.ApplicationInsights.dlltook about51.6ms.Microsoft.ApplicationInsights.dlland enable tiered compilation, the jitting time drops to about98.9ms. Detailed information can be found at the end.NOTE: Each commit is self-contained and the purpose of the commit is described by the commit message. So it would be easier to review per commit.
Compared with Windows PowerShell
The optimized pwsh is still about
75msslower than Windows PowerShell. The main reason is jitting time difference, even though we crossgen all the assemblies in the table below except forpwsh.dll.More work will be done to further bring down the jitting time at startup.
Reference Set Improvement
Impacting memory size loaded from disk (total): 5.9% less pages (606 / 10289 pages), 6% less memory (2.4 / 40.2 mb). The comparison of the image pages being loaded during startup before and after this PR is as follows:
Jitting Time Improvement
Windows PowerShell
Before crossgen'ing
Microsoft.ApplicationInsights.dlland applying tiered compilationAfter crossgen
Microsoft.ApplicationInsights.dlland applying tiered compilationStartup Detailed Measurement Record
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.[feature]if the change is significant or affects feature tests