When writing powershell sometimes the allure of writing good looking small oneliners might be the wrong thing. For instance if you have a large amount of objects and then want to run Where-Object against them. If we do a oneliner and include something dynamic in a Where-Object, we will force Powershell to execute it everytime. This might be what we want BUT, if we want to compare against a computed date. There is no need to calculate what day it was 7 days ago each time. To prove my point I have written a small powershell script. It will generate 1 000 000 random numbers between 0 and 6, it will then compare it to the current day of week.

Measure-Command {
$time = (Get-Date).DayOfWeek.value__
1..1000000|ForEach {Get-Random -Minimum 0 -Maximum 6}|Where-Object {$time -eq $_}
} | Select-Object TotalSeconds
Measure-Command {
1..1000000|ForEach {Get-Random -Minimum 0 -Maximum 6}|Where-Object {(Get-Date).DayOfWeek.value__ -eq $_}
} | Select-Object TotalSeconds

So what did we figure out, that the Get-Date is run every time. So depening on what you are checking against, you could save lots of cpu time.

Findings…

But then again if we decide not to use Cmdlets (which is the recommended way) and go the .NET way. We get a new result. As always .NET is faster, but not as easy to read. If you want it realllly fast, you can code it in Assembler.

Measure-Command {
1..1000000|ForEach {Get-Random -Minimum 0 -Maximum 6}|Where-Object {[datetime]::Now.DayOfWeek.value__ -eq $_}
}| Select-Object TotalSeconds

So what is result for .NET?

So.. Just wanted to get this out there.