zsh-users
 help / color / mirror / code / Atom feed
* fast subshell
@ 2018-04-01 15:59 Ray Andrews
  2018-04-01 18:39 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Ray Andrews @ 2018-04-01 15:59 UTC (permalink / raw)
  To: Zsh Users

So, now that I am awake to the usefulness of subshells in a function, 
I'm still exploring the implications on speed since a subshell sounds 
like it would be a lot of work.  However, using it to  control my old 
friend IFS, whereasI had previously done this:


     local IFS=$'\n' # Must split on newlines only.
     all_matches=( $( whence -mavS $@ ) )
     IFS=$OLD_IFS

... now trying:


(
     IFS=$'\n' # Must split on newlines only.
     all_matches=( $( whence -mavS $@ ) )
)

... and the interesting thing is that the former executes a stress test 
in ca. 290 mS, but the latter in ca. 250 mS.  The difference isn't 
significant in the real world, but it is hard to understand, it seems 
strange that the subshell would be faster. Is this possible?  If so, how 
should I understand it?  It seems as if a subshell is a rather 'lite' 
thing after all, in the above it seems to be hardly more than a scoping 
of IFS.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: fast subshell
  2018-04-01 15:59 fast subshell Ray Andrews
@ 2018-04-01 18:39 ` Bart Schaefer
  2018-04-01 20:45   ` Ray Andrews
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2018-04-01 18:39 UTC (permalink / raw)
  To: Ray Andrews; +Cc: Zsh Users

On Sun, Apr 1, 2018 at 8:59 AM, Ray Andrews <rayandrews@eastlink.ca> wrote:
>
>     local IFS=$'\n' # Must split on newlines only.
>     all_matches=( $( whence -mavS $@ ) )
>     IFS=$OLD_IFS
>
> (
>     IFS=$'\n' # Must split on newlines only.
>     all_matches=( $( whence -mavS $@ ) )
> )
>
> ... and the interesting thing is that the former executes a stress test in
> ca. 290 mS, but the latter in ca. 250 mS.  The difference isn't significant
> in the real world, but it is hard to understand, it seems strange that the
> subshell would be faster. Is this possible?

$(...) is always going to create one subshell.

How expensive a subshell is, may depend on several things:  How the
operating system implements process forking; how much memory your
current shell is using at the time; how busy the system otherwise is;
what kind of multithreading your processor supports; and so on.

It's quite possible that doing the memory management for the
assignment to all_matches in a newly forked process is faster than in
the original shell (perhaps because the subshell never needs to free
it again?).  There is also some overhead involved in saving/restoring
IFS with "local" which you are avoiding.

Also there's really no reason to do both "local IFS=..." and
"IFS=$OLD_IFS", the whole point of the "local" is to allow zsh to do
the save/restore of IFS for you.  If you only need the change of $IFS
for "whence" then you can do it with an anonymous function:

  (){ local IFS=$'\n'; all_matches=( $( whence -mavS $@ ) ) }

Or you can do it without changing IFS at all, like this:

  all_matches=( ${(f)"$( whence -mavS $@ )"} )


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: fast subshell
  2018-04-01 18:39 ` Bart Schaefer
@ 2018-04-01 20:45   ` Ray Andrews
  0 siblings, 0 replies; 3+ messages in thread
From: Ray Andrews @ 2018-04-01 20:45 UTC (permalink / raw)
  To: zsh-users

On 01/04/18 11:39 AM, Bart Schaefer wrote:
>
> It's quite possible that doing the memory management for the
> assignment to all_matches in a newly forked process is faster than in
> the original shell (perhaps because the subshell never needs to free
> it again?).  There is also some overhead involved in saving/restoring
> IFS with "local" which you are avoiding.
It's rather interesting.  I suppose the deepest gurus could actually 
discuss the nuts and bolts in detail.  Meanwhile my fears of some 
dreadful overhead are dead.
>
> Also there's really no reason to do both "local IFS=..." and
> "IFS=$OLD_IFS"
I need the thing restored for use latter in the same function. I've 
since seen that:

(
IFS=...
...
)

Somehow screws up, I'm not sure why but it has effects outside the 
parenthesis.  Issues with a subshell within a subshell?  Don't seem right.
>    (){ local IFS=$'\n'; all_matches=( $( whence -mavS $@ ) ) }
I'll try that.
> Or you can do it without changing IFS at all, like this:
>
>    all_matches=( ${(f)"$( whence -mavS $@ )"} )
>
Now that's the 'real' answer.  Direct control within the statement 
itself.   Gotta get used to these nested parameters, it's not really 
that scary.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-04-01 20:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-01 15:59 fast subshell Ray Andrews
2018-04-01 18:39 ` Bart Schaefer
2018-04-01 20:45   ` Ray Andrews

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).