5

I tried a few options to iterate my directories and get a huge performance difference between the following commands:

Slow:

Get-ChildItem -Directory -Force -Recurse -Depth 3 -Include '$tf'

Fast:

Get-ChildItem -Directory -Force -Recurse -Depth 3 | Where-Object Name -eq '$tf'

Could someone explain me why the first statement is much slower than the second?

Hauke Lü
  • 75
  • 7
  • 1
    Do you remember if you could've used the `-Filter` switch to achieve your goal? According to [the documentation](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.3#-filter) "Filters are **more efficient** than other parameters. The provider applies filter when the cmdlet gets the objects rather than having PowerShell filter the objects after they're retrieved." – Nate Anderson Feb 21 '23 at 20:30
  • 1
    Thanks for the hint. It is working even better than the Where-Object (in my case). – Hauke Lü Feb 27 '23 at 12:48

1 Answers1

11

Get-ChildItem is a provider cmdlet - that means that a bulk of its actual work is offloaded to an underlying provider, likely the FileSystem provider in your case.

The provider itself doesn't actually support the -Include/-Exclude parameters, that's one of the few things that the cmdlet takes care off - and for the file system provider this is ultra heavy double-work, because the cmdlet needs to recurse down through the file system hierarchy to figure out whether it needs to apply an exclusion or an inclusion based on a parent directory name, you can see how this is implemented here.

So by using -Include against the file system provider, you're asking PowerShell to do an immense amount of double work.

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206