hg lim
hg lim

Reputation: 185

Is my PowerShell script slow because of calculated properties?

I'm fairly new to PowerShell but find it useful when I just need some automation instead of having to break out IDE or code editor+compiler. I have a script that will list files, run it through a custom function and then select specific properties for exporting to CSV.

ls .\mydir | Convert-ToMyObject | select -Property IdKey, Timestamp `
  | Export-Csv ".\list.csv"

The script takes about 20-30 minutes to parse through ~45K files.

However, as soon as I change it as follows, it takes a long, long time to process (at this point, it's been about 2 hours and only finished ~25K files).

ls .\mydir | Convert-ToMyObject `
  | select -Property IdKey, @{Name="year";Expression={Timestamp.Year}}, `
    @{Name="month";Expression={Timestamp.Month}}, @{Name="day";Expression={Timestamp.Day}}, `
    @{Name="hour";Expression={Timestamp.Hour}}, @{Name="minute";Expression={Timestamp.Minute}}, `
    @{Name="second";Expression={Timestamp.Second}}, @{Name="millisecond";Expression={Timestamp.Millisecond}} `
  | Export-Csv ".\list.csv"

I can't figure out what is the cause of this (my google-fu ain't strong enough) and hope someone can help enlighten me. Is it due to the calculated properties? Or the calls to get the datetime components? Or both?

Upvotes: 1

Views: 428

Answers (1)

Bacon Bits
Bacon Bits

Reputation: 32180

Your syntax for calculated properties is wrong. You're missing the pipeline object ($_) in the expression. Compare this:

gci | select -Property @{Name="year";Expression={LastWriteTime.Year}}

To this:

gci | select -Property @{Name="year";Expression={$_.LastWriteTime.Year}}

The first version runs very slowly (about 100 ms per file) and produces no useful output at all. The second one is very fast.

Change your code to this:

select -Property IdKey, @{Name="year";Expression={$_.Timestamp.Year}}, `
@{Name="month";Expression={$_.Timestamp.Month}}, @{Name="day";Expression={$_.Timestamp.Day}}, `
@{Name="hour";Expression={$_.Timestamp.Hour}}, @{Name="minute";Expression={$_.Timestamp.Minute}}, `
@{Name="second";Expression={$_.Timestamp.Second}}, @{Name="millisecond";Expression={$_.Timestamp.Millisecond}}

Upvotes: 2

Related Questions