profesorfalken / jPowerShell

Simple Java API to interact with PowerShell console
Apache License 2.0
218 stars 84 forks source link

Bad performance when executing commands with multiple lines of output. #32

Open Tuupertunut opened 6 years ago

Tuupertunut commented 6 years ago

When executing commands with PowerShell.executeCommand(String), jPowerShell seems to wait the 10ms waitPause between every output line that the command prints.

For example, if you try ls on a folder with 200 files, it takes approximately 2000 ms or 2 seconds to execute the command because it prints a little over 200 rows of output. This introduces a huge performance overhead on very simple commands.

profesorfalken commented 6 years ago

I will check it.

Thanks

zik43 commented 6 years ago

thx you its a real problem

profesorfalken commented 6 years ago

Hello,

I have just took a look. In fact when I created jPowershell I did not think on performance, because my needs were to have something stable that works. Reading powershell console is a real pain as you can see in the code, because the reader blocks very easily. The vast mayority of examples you can find on internet, just does not work.

However, for this case (list of files), you can tweak it changing the configuration. You can, for example, change the waitPause to 1. That will reduce the latence and to list 200 files il will take 200ms, which is acceptable, in my opinion.

You can learn more about how to change the configuration in the section Configure jPowerShell Session of the README file.

Best regards

Tuupertunut commented 6 years ago

Meanwhile I have created my own library where I used many of your ideas from jPowerShell and improved them. You may want to take a look: https://github.com/Tuupertunut/PowerShellLibJava

The way I fixed this performance issue was by using end-of-command strings, kind of like you did for scripts, but for individual commands. The reader reads until an end-of-command string is printed, and that's when it knows the command has ended. The user command is wrapped into a powershell "Invoke-Expression" statement, so the end-of-command string will always be printed even if the command throws errors. Meanwhile it also records the error stream with another reader and at the end-of-command it checks whether anything was written to it.

Lampros7 commented 3 years ago

@profesorfalken Did you ever implemented any similar feature(s) to the ones @Tuupertunut added to his forked library?

It's been some time since then and I really liked Tuuper's library with the end of line strings so I've been using it, but I really liked some unique features and updates that you've been adding too.

Let me know - thanks,

Lampros