MicrosoftDocs / PowerShell-Docs

The official PowerShell documentation sources
https://learn.microsoft.com/powershell
Other
1.99k stars 1.58k forks source link

`New-Object` cmdlet vs `[PSCustomObject]` #11491

Open iRon7 opened 1 day ago

iRon7 commented 1 day ago

Type of issue

Missing information

Feedback

Even it is implied in the section Avoid wrapping cmdlet pipelines section and covered in the Everything you wanted to know about PSCustomObject / Legacy approach. Creating PSCustomObject is a very common use case and the impact of using the New-Object cmdlet vs [PSCustomObject]@{ ... } type initiator is quite severe:

Measure-Command {
    for ($i = 0; $i -lt 1e6; $i++) {
        $resultObject = [PSCustomObject]@{
            Name = 'Name'
            Path = 'FullName'
        }
    }
}

Measure-Command {
    for ($i = 0; $i -lt 1e6; $i++) {
        $resultObject = New-Object -TypeName PSObject -Property @{
            Name = 'Name'
            Path = 'FullName'
        }
    }
}
Syntax Windows PowerShell (5.1) PowerShell 7.4.5 (Core)
New-Object 90 secondes 39 secondes
[PSCustomObject] 8 secondes 5 secondes

I recommend to make a special note in this performance document too.

Page URL

https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/performance/script-authoring-considerations?view=powershell-7.4

Content source URL

https://github.com/MicrosoftDocs/PowerShell-Docs/blob/main/reference/docs-conceptual/dev-cross-plat/performance/script-authoring-considerations.md

Author

@sdwheeler

Document Id

9818d91b-8c5f-337a-f5e1-7a40abd5fd1a

iRon7 commented 1 day ago

Actually this presumably counts for any object creation including something like: New-Object System.Drawing.Size(800, 600) --> [System.Drawing.Size]::new(800, 600)

Fyi, the related StackOverflow question I was trying to answer: https://stackoverflow.com/q/79119400/1701026

sdwheeler commented 1 day ago

@iRon7 I was thinking the same thing about new()' vs 'New-Object.

Another example:

Measure-Command {
    $test = 'new() method'
    for ($i = 0; $i -lt 1e6; $i++) {
        $sb = [System.Text.StringBuilder]::new(1000)
    }
} | Select-Object @{n='Test';e={$test}},TotalSeconds

Measure-Command {
    $test = 'New-Object'
    for ($i = 0; $i -lt 1e6; $i++) {
        $sb = New-Object -TypeName System.Text.StringBuilder -ArgumentList 1000
    }
} | Select-Object @{n='Test';e={$test}},TotalSeconds

Test         TotalSeconds
----         ------------
new() method         4.67
New-Object          21.56