Skip to content

Feature Request - Where-Object speed improvements #9941

Closed

Description

Summary of the new feature/enhancement

As it stands I've stopped using Where-Object in performance-related scenarios. I used it a lot when creating different scripts but then I found out it's actually 7-10x slower than simple foreach loop.

$UsersAll = Get-ADUser -Properties Manager, DisplayName, EmailAddress -Filter '*'
$UsersWithManagers = foreach ($User in $UsersAll) {
    $Manager = ($UsersAll | Where-Object { $User.Manager -eq $_.DistinguishedName })
    [PSCustomobject] @{
        SamAccountName = $User.SamAccountName
        Manager        = $User.Manager
        ManagerDisplay = $Manager.DisplayName
        ManagerEmail   = $Manager.EmailAddress
    }
}
$UsersWithManagers | Format-Table -AutoSize

This takes 7 minutes 54 seconds on a domain of size 4412 users. With foreach approach like this:

$UsersAll = Get-ADUser -Properties Manager, DisplayName, EmailAddress -Filter '*'
$UsersWithManagers = foreach ($User in $UsersAll) {
    $Manager = foreach ($_ in $UsersAll) {
        if ($User.Manager -eq $_.DistinguishedName) {
            $_
            break
        }
    }
    [PSCustomobject] @{
        SamAccountName = $User.SamAccountName
        Manager        = $User.Manager
        ManagerDisplay = $Manager.DisplayName
        ManagerEmail   = $Manager.EmailAddress
    }
}
$UsersWithManagers | Format-Table -AutoSize

It takes just 59 seconds. I ended up using hashtable for that particular problem (https://evotec.xyz/how-i-didnt-know-how-powerful-and-fast-hashtables-are/) but the main idea here is that Where-Object is just slow for larger loops.

It would be really cool to "fix" this in PowerShell 7 so Where-Object can once again be used as GO TO to solution for filtering stuff.

Activity

  1. iSazonov commented on Jun 19, 2019

    @iSazonov
    Collaborator

    Related article https://learn-powershell.net/2015/02/20/a-look-at-filtering-performance-in-powershell/

    I think there is 2 slow thinks:

    • pipeline itself
    • where-object internally

    I guess we could transform Where-Object to Filter function and get up to 20x improvements.
    The code references:

    object result = _script.DoInvokeReturnAsIs(
    useLocalScope: false,
    errorHandlingBehavior: ScriptBlock.ErrorHandlingBehavior.WriteToCurrentErrorPipe,
    dollarUnder: InputObject,
    input: new object[] { _inputObject },
    scriptThis: AutomationNull.Value,
    args: Array.Empty<object>());
    if (_toBoolSite.Target.Invoke(_toBoolSite, result))
    {
    WriteObject(InputObject);
    }

    if (isFilter)
    {
    this.ProcessBlock = new NamedBlockAst(statements.Extent, TokenKind.Process, statements, true);
    SetParent(ProcessBlock);
    }
    else

  2. paule96 commented on Aug 14, 2020

    @paule96

    I have also an example for this problem. If you use there Where-Object function of PowerShell it is slow. If you use the Linq function of the object you get twice the perfomance, with more or less the same code..

    image

  3. vexx32 commented on Aug 15, 2020

    @vexx32
    Collaborator

    Point of clarity, that .Where() method has absolutely nothing to do with Linq; Linq extension methods aren't supported in PS and can't be used without accessing them directly as static methods (i.e., [System.Linq.Enumerable]::Where()). The method you're using is specific to PS's method binding, it's documented in the about_arrays help topic :)

    But yeah, pipeline binding and processing has some overhead, for sure. 🙂

  4. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  5. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  6. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  7. microsoft-github-policy-service commented on Nov 23, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Issue-Enhancementthe issue is more of a feature request than a bugResolution-No ActivityIssue has had no activity for 6 months or moreWG-Engine-Performancecore PowerShell engine, interpreter, and runtime performance

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions