Hacker News new | ask | show | jobs
by Graphon 5109 days ago
While powershell is a valuable and interesting option, the problem with it is that it changes the basic metaphor.

For 40 years unix shells and their descendants and derivatives including cmd.exe have used files and text streams as the metaphor for interconnecting processes. Powershell changes that, and it means the output of one command goes to the input of another command as "objects".

This can be powerful, but it is also very disorienting. Which means it can be hard to learn to do even basic things in powershell, things that would take only a pipe or two and a couple unxutls programs in cmd.exe.

In cmd.exe, easy things are easy and hard things can be really hard. In powershell, hard things are hard (as opposed to "really hard") and easy things are hard.

3 comments

I'm not a fan of powershell but I have to use it in my line of work.

The only thing that I find sucks is that the pipeline is slow as snails. For example, an svnadmin dump piped to a file which takes 8 mins in cmd.exe takes 14 hours in powershell...

Apart from that it's bearable!

The only thing that I find sucks is that the pipeline is slow as snails.

This is because CreateProcess in Windows is slow. It's the reason that run make on Cygwin on Windows for not-that-large Makefiles is really, really slow. The same Makefile on UNIX and Windows differ in startup time by a wide margin. It's really painful to type "make ..." and sit there for 30 seconds on a fast machine.

CreateProcess is only being called once in this case i.e. to spawn svnadmin. The exact script does the following:

   svnadmin dump d:\repo > repo.dump
The output from svnadmin has a lot of lines. Due to the fact that PS is written on top of the CLR, it reads each line into an immutable string before writing it to a file. So for every line it has to create a new System.String object and as another poster said GC it later. Also as lines are not predictable length it has to buffer them resulting in more overhead.

Effectively where *NIX shells use a fixed size buffer for pipe operations and operate on streams, PS has to convert it to lines first before writing it out.

That doesn't work when you have approximately 25 bytes per line and a 12Gb file which is where the issue is.

I can appreciate the technical explanation as a programmer, but as an end-user of PS: I don't care. It's slow.
For the majority of tasks it's fast enough. There are a few edge cases though.
That's when doing it the Enterprisey way bites you in the ass..
I don't understand your comment. There's nothing enterprisey about it.
I mean that from Microsoft's perspective. They apparently decided to put an object around something as simple and essential to performance as a line buffer. That's when you should have hired a system programmer to do that job.

Don't get me wrong, I actually like their approach in developing an OO-shell - but if it hurts performance that much someone has taken that paradigm too far. It's the typical case of someone with a hammer (OO programmer) trying to approach everything like it were nails.

Really 14hours?!

Have you tried to change the way the dump is done?

Well you can only pipe to file as the output is on stdout. We just ran it through cmd.exe instead. 8 mins is fine - it's a 12Gb repo.

I assume it's related to PS converting every line into a system.string.

Followed by massive GC most likely. Thanks for sharing.
perhaps the real solution to the performance issue you mention is to have svnadmin actually write to a target file instead of crossing process boundaries to redirect stdout ?

have you tried :

Start-Process '{PATHTOSUBVERSION}\svnadmin' -argumentlist "dump {PATH_TO_REPOSITORY}" -RedirectStandardOutput c:\temp\repodump.dmp -Wait

more examples here : http://www.youtube.com/watch?v=9sn2L0E5jT8

Never tried that. I will have a go. Thanks for the suggestion.

Unfortunately its very verbose for a simple case which works fine in cmd so I'm not sure that it warrants using that tool

I do only easy things with Powershell and I found it much nicer than classical shells. It's more consistent in the command names and parameter passing. You also need to learn far fewer commands, because Powershell follows the Unix philosophy of small tools that do one thing well much more than Bash+Unix tools. For example if you do "ls" then you get a table where one of the columns is LastWriteTime. Want to sort by that column? "ls | sort lastwritetime". This works without hassle because ls returns a list of objects, and sort sorts a list of objects by a given property, instead of serializing everything to text that would need to be parsed first. I'm sure that Unixes' ls has an option built in to ls to sort by that column, but off the top of my head I have no idea what it is, and many commands that output lists of things do not have that option.

You even get autocompletion across commands: if you type "ls | sort _" where _ is the cursor, then you get a list of properties that you can sort objects returned by ls by (LastAccessTime, LastWriteTime, Extension, etc).

Just one more way that ms produces developers that cant do anything on their own, or outside visual studio.

Just my experience, but most ms developers have been crippled by their tooling. Powershell is no exception.

"Powershell makes it easier to discover commands"

"You're weak and have been crippled by your tools."

o_o You're suffering from Stockholm Syndrome. Upgrade your tools and be free from menial labor.

I disagree. All the time spent finding and learning new tools can be spent getting things done. I use bash, vi, grep, and man and I can get 95% of what I need done with just those.
Good for you. As long as we're making up numbers: I can get 100% of what I need done in 80% of the time as you, simply because I use superior tools that eliminate menial labour. Get out of your bubble.
> it means the output of one command goes to the input of another command as "objects".

Only if both commands support objects. If one of them doesn't then PowerShell just deals with text. I've sent the output of PowerShell commands to perl scripts and GNU utils without any problems. It just worked. I'm still a powershell newbie, and this has made it easy for me to learn it while still using what I know.