Posts RSS Comments RSS 253 Posts and 411 Comments till now

Interpreting > Parsing (who knew!)

I found out some interesting information yesterday. I thought I would share it.

Back Story:
A question was asked on how to include $env:ComputerName to a string. I quickly piped up “HA! That is easy just wrap $() around the variable and it will work.” While this indeed works and is what I have been doing for the last couple of years… There was a better way!

It turns out that Jim Truher was watching this particular thread discussion and quickly informed me that this was “quite inefficient” and I should use ${} instead. So of course, I had to know why. Luckily Bruce Payette was also watching this thread and explained the following.

I hope he doesn’t mind if I quote him.

“The big difference is whether the parser gets involved or not. In the ${foo} case, the interpreter simply extracts the string, looks up the variable and inserts the result. In the $($var) case, the string is extracted, parsed and then executed which is more overhead.”

More Info (provided by Keith Hill):
$() is used within strings to evaluate statements (potentially multiple statements) and the results are converted into a string (Using OFS.)

${} is simply used to prevent the interpreter from “interpreting” the name of the variable instead it is treated as the literal name of the variable

Moral of the Story?
From now on I am using ${} when no evaluating is needed.

Jims Blog
http://jtruher.spaces.live.com/

Keith Hill has an awesome Series called Effective Powershell
http://keithhill.spaces.live.com/

Bruce hangs out on the Powershell Forum
http://blogs.msdn.com/PowerShell/

Bruce also wrote Windows Powershell in Action
http://www.manning.com/payette/

p.s. I tested this with this code

# with ${}
( Measure-Command {1..10000 | %{ "${env:path}" } } ).TotalMilliseconds
# vs with $()
( Measure-Command {1..10000 | %{ "$($env:path)" } } ).TotalMilliseconds

7 Responses to “Interpreting > Parsing (who knew!)”

  1. on 28 Feb 2008 at 8:43 amRobbie Foust

    Very useful information! In fact, probably something I’ll be using on a daily basis from now on. 😉

  2. on 18 Mar 2008 at 4:50 amperost

    Hi Brandon.

    Do I misunderstand it all or? Parsing env:path can be done directly without any () or {}. Simply use “$env:path”, colon – e.g. the variable scope or drive delimiter – is automatically parsed after $, so why use it at all?

  3. on 18 Mar 2008 at 9:58 amBrandon

    It is not that it doesn’t work. It is about how fast it works. If you would have to do this 100 or even 1000s of times. It makes a difference.

    Good Catch btw.

  4. on 04 Sep 2008 at 3:33 amstefand

    I think you have a typo
    In the first line you write “I quickly piped up “HA! That is easy just wrap @() … ”
    I think it should be
    I quickly piped up “HA! That is easy just wrap $() …

  5. on 04 Sep 2008 at 8:23 amtshell

    Good Catch… THANKS!

  6. on 18 Feb 2010 at 5:25 amantize

    On my machine:

    PS C:\Users\Me> ( Measure-Command {1..10000 | %{ “${env:path}” } } ).TotalMilliseconds
    2793.7212
    PS C:\Users\Me> ( Measure-Command {1..10000 | %{ “$($env:path)” } } ).TotalMilliseconds
    2659.4779

    $() actually was quicker… (PS V2)

  7. on 18 Feb 2010 at 5:27 amantize

    On my machine:

    PS C:\Users\Me> ( Measure-Command {1..10000 | %{ “${env:path}” } } ).TotalMilliseconds
    2793.7212
    PS C:\Users\Me> ( Measure-Command {1..10000 | %{ “$($env:path)” } } ).TotalMilliseconds
    2659.4779

    $() actually was quicker…

    (PS V2)

Trackback this post | Feed on Comments to this post

Leave a Reply

You must be logged in to post a comment.