2

Like with numerics?

For example,

$string = "Hello"
$string =+ " there"

In Perl you can do

my $string = "hello"
$string .= " there"

It seems a bit verbose to have to do

$string = $string + " there"

or

$string = "$string there"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mark Allison
  • 6,838
  • 33
  • 102
  • 151

2 Answers2

8

You actually have the operator backwards. It should be +=, not =+:

$string = "Hello"
$string += " there"

Below is a demonstration:

PS > $string = "Hello"
PS > $string
Hello
PS > $string += " there"
PS > $string
Hello there
PS >

However, that is about the quickest/shortest solution you can get to do what you want.

5

Avoid the increase assingment operator (+=) for building strings

As for using the increase assignment operator (+=) to create a collection, strings are also mutual, therefore using the increase assignment operator (+=) to build a string might become pretty expensive as it will concatenate the strings and assign (copy!) it back into the variable. Instead I recommend to use the PowerShell pipeline with the -Join operator to build your string.
Apart from the fact it is faster it is actually more DRY as well:

$String = 'Hello', 'there' -Join ' ' # Assigns: 'Hello there'

Or just

-Join @('One', 'Two', 'Three') # Yields: 'OneTwoThree'

For just a few items it might not make much sense but let me give you a more common example by creating a formatted list of numbers, something like:

[Begin]
000001
000002
000003
[End]

You could do this:

$x = 3
$String = '[Begin]' + [Environment]::NewLine
for ($i = 1; $i -le $x; $i++) { $String += '{0:000000}' -f $i + [Environment]::NewLine }
$String += '[End]' + [Environment]::NewLine

But instead, you might actually do it the PowerShell way:

$x = 3
$String = @(
    '[Begin]'
    for ($i = 1; $i -le $x; $i++) { '{0:000000}' -f $i }
    '[End]'
) -Join [Environment]::NewLine

Performance Testing

To show the performance decrease of using the increase assignment operator (+=), let's increase $x with a factor 1000 up till 20.000:

1..20 | ForEach-Object {
    $x = 1000 * $_
    $Performance = @{x = $x}
    $Performance.Pipeline = (Measure-Command {
        $String1 = @(
            '[Begin]'
            for ($i = 1; $i -le $x; $i++) { '{0:000000}' -f $i }
            '[End]'
        ) -Join [Environment]::NewLine
    }).Ticks
    $Performance.Increase = (Measure-Command {
        $String2 = '[Begin]' + [Environment]::NewLine
        for ($i = 1; $i -le $x; $i++) { $String2 += '{0:000000}' -f $i + [Environment]::NewLine }
        $String2 += '[End]' + [Environment]::NewLine
    }).Ticks
    [pscustomobject]$Performance
} | Format-Table x, Increase, Pipeline, @{n='Factor'; e={$_.Increase / $_.Pipeline}; f='0.00'} -AutoSize

Results:

    x Increase Pipeline Factor
    - -------- -------- ------
 1000   261337   252704   1,03
 2000   163596    63225   2,59
 3000   432524   127788   3,38
 4000   365581   137370   2,66
 5000   586370   171085   3,43
 6000  1219523   248489   4,91
 7000  2174218   295355   7,36
 8000  3148111   323416   9,73
 9000  4490204   373671  12,02
10000  6181179   414298  14,92
11000  7562741   447367  16,91
12000  9721252   486606  19,98
13000 12137321   551236  22,02
14000 14042550   598368  23,47
15000 16390805   603128  27,18
16000 18884729   636184  29,68
17000 21508541   708300  30,37
18000 24157521   893584  27,03
19000 27209069   766923  35,48
20000 29405984   814260  36,11

Note that there even faster (less idiomatic) ways to build a string in PowerShell, for this see: PowerShell scripting performance considerations - String addition (thanks to Santiago Squarzon for his contribution in this section).

iRon
  • 20,463
  • 10
  • 53
  • 79
  • 1
    @specializt, *"its actually more work to care about it than to ignore"* that depends on the language you're used to. As a matter of fact, using the [PowerShell Pipeline](https://docs.microsoft.com/powershell/module/microsoft.powershell.core/about/about_pipelines) for adding multiple strings like `$String = -Join ( 'String1', 'String2', 'String3', 'StringX')` is at least [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself#:~:text=%22Don't%20repeat%20yourself%22,data%20normalization%20to%20avoid%20redundancy.)er than repeatedly reassigning the additions, like: `$String += 'StringX'`. – iRon Mar 31 '22 at 09:23
  • 2
    It is true that `+=` is expensive for concatenating strings however negligible for small ops, however for true performance the best is a StringBuilder. In addition it's worth noting that these tests are executing in the caller's scope since `Measure-Command` dot sources the scriptblock, performance tests should always be executed in their own scope. https://gist.github.com/santisq/0b00a5ad00e7614a04fc83465a6e4d9f#file-results-md Shows more accurate results – Santiago Squarzon Jun 23 '23 at 15:18
  • 1
    https://github.com/MicrosoftDocs/PowerShell-Docs/issues/10201 feel free to chime in if you have any observation ;) – Santiago Squarzon Jun 23 '23 at 20:27