-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Progress bar can significantly impact cmdlet performance #2138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
How can you be sure that it's the progress bar? With Moreover, I did your tests and found that the standard deviation is rather great (poor network here in China). Please do observe Task Manager for the network speed and also do more statistics. If the network is perfect (I hosted a file locally and tried to download via And, could you include the |
PSEdition Core |
I also see the progress bar slowing down Invoke-WebRequest by >50X on a fast internet connection. Every time I write a script that uses Invoke-WebRequest I need to include code to temporarily change Here's my output from using Invoke-WebRequest to download the same file as @SteveL-MSFT, without and then with progress:
It would be nice to be able to have reasonable progress when downloading a file. Perhaps if there were a way to adjust the progress reporting interval to several KB instead of every byte (!!) then the overhead wouldn't be so bad. |
This issue also affects Expand-Archive. For a large archive (10 MB with 3495 files), expanding it takes over 4X long with progress compared to without. |
Changed title to be a generic issue with the progress bar. |
Yeah, this is pretty bad ...
|
I remember noticing how much of a blocker progress writing was when I wrote the PSCX GAC provider back in 2007:
We decided to only write a record on every fifth iteration. |
It's very simple (write a record on every fifth iteration). 👍 Just seems the compromise is not always the optimal. |
@iSazonov Yeah. I'm just saying that it's a problem that's been there since the beginning. Skipping records doesn't solve all issues. |
@oising This is not a criticism from me. I just asked your opinion on "async" since you have experience with the problem. |
I did some research in codes and found that a partial solution already exists in Checkpoint-Computer if (recordType == ProgressRecordType.Processing)
{
TimeSpan timeSinceProgressWasWrittenLast = DateTime.UtcNow - lastTimeProgressWasWritten;
if (timeSinceProgressWasWrittenLast < TimeSpan.FromMilliseconds(200))
{
return;
}
}
lastTimeProgressWasWritten = DateTime.UtcNow; I used this for the test. Working call chain for WriteProgress is cmdlet.cs -> MshCommandRuntime.cs -> InternalHostUserInterface.cs -> ConsoleHostUserInterface.cs -> ConsoleHostUserInterfaceProgress.cs In HandleIncomingProgressRecord (ConsoleHostUserInterfaceProgress.cs) I "mask" _progPane.Show(_pendingProgress); TimeSpan timeSinceProgressWasWrittenLast = DateTime.UtcNow - _lastTimeProgressWasWritten;
if (timeSinceProgressWasWrittenLast > TimeSpan.FromMilliseconds(200))
{
_progPane.Show(_pendingProgress);
_lastTimeProgressWasWritten = DateTime.UtcNow;
} Performance tests have shown that after this change, the difference between I played with If this is the correct place for the patch, I can do PR. @daxian-dbw @lzybkr Could you comment please? |
That's an interesting idea, I use a similar hack in PSReadline to minimize rendering calls. There is one big problem with this approach - if we skip an update and don't see any progress updates for a long time, the current "hung" state would be misleading because the last update wasn't rendered. If we could render updates on a timer, that might be ideal. |
@lzybkr Thanks for comment! |
It turns out the timer fix causes some potential race conditions (see the issue #2800 and discussions in PR #2771). So the timer change was reverted with PR #2806 for now, and we need to different approach to address this problem. It would be very helpful if someone can run a profiler on |
@daxian-dbw It seems that we can simply control the time delta in HandleIncomingProgressRecord , but my earlier tests showed that is significantly slower. |
From @daxian-dbw
|
The Actually there are three problems in one place, which might require different solutions:
|
Speed up Azure CI installing Windows dependencies There is known issue where PowerShell is unreasonably slow downloading files due to an issue with rendering the progress bar, see this [issue](PowerShell/PowerShell#2138) That issue is fixed in PowerShell Core (available in Azure Pipelines as pwsh.exe) but it can also be worked around by setting: $ProgressPreference = 'SilentlyContinue' I measured downloading LLVM and it took about 220s before, 5s after, so the improvement is significant.
…ipt. The progress bar causes significant performance issues, see PowerShell/PowerShell#2138 (comment) for more details.
Disables the PowerShell progress bar for the `Invoke-WebRequest` cmdlet calls in the `Invoke-GHRestMethod` and `Invoke-SendTelemetryEvent` functions due to known performance issues in PowerShell 5.1. Reference: [Progress bar can significantly impact cmdlet performance.](PowerShell/PowerShell#2138) Fixes #227
Hello folks! I ran my test using As I read above, there is, or used to be a fix. Is it still there? |
@max06 this has already been fixed in PowerShell. Windows PowerShell most likely will never get that fix. You can get around it on Windows PowerShell by using setting https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.2#progresspreference to SilentlyContinue. |
@ThomasNieto Thank you for your quick response! So, Windows Powershell is different from this one? I never knew that 😲 I'm also not using PS very often, a colleague reported this issue while setting up a new server - I'll forward your hint to him. |
Uh oh!
There was an error while loading. Please reload this page.
Repro Steps :
Compare perf of WebClient, BITS and Invoke-WebRequest:
Expected: Transfer speeds don't differ too much (maybe Invoke-WebRequest should be a bit faster than BITS which performs the transfer in background.)
Actual: 10x slowdown for Invoke-WebRequest
The text was updated successfully, but these errors were encountered: