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,030
  • 21
  • 100
  • 124
Mark Allison
  • 6,486
  • 28
  • 96
  • 146

2 Answers2

7

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.

2

Avoid += 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 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

See also: PowerShell scripting performance considerations - String addition

iRon
  • 14,879
  • 7
  • 40
  • 67
  • i'm gonna be honest here real quick: literally not a single, **professional** developer on the planet cares about performance if it comes to powershell - its actually more work to care about it than to ignore it and get on with important things _(like functionality, testability, readability and so on)_. We are in the 21st century. There are mobile processors in the octa-core variant and solid state drives with unbelievable throughput. Performance does not matter anymore. Embedded dev is dying. Sorry. – specializt Mar 24 '22 at 10:27
  • @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
  • no, it doesnt. Performance is a measure of relative execution speed and/or throughput. There is literally no causal connection between it and software-design concepts - except for performance-oriented ones for rather extreme environments _(like deep space exploration, military utilities and whatnot)_ - which cannot be held as an example for anything else other than themselves and similar ones; because they are **extreme** with a large gap between it and the "vast majority" of environments. – specializt Apr 05 '22 at 21:58