This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Zsh filename completion sluggishness?


On Thu, 13 Feb 2003, Jason Tiller wrote:

> Hello, All, :)

Hi Jason,

> [Pardon me if I'm asking this in the wrong place.  I thought to check
> here before going to the Zsh Users list.]
> 
> For the last week or so I've been experimenting with Zsh as a
> replacement for bash, mainly because of Zsh's adherents claim that
> it's the most powerful shell for interactive, command-line use.  I
> come from JPSoft's fabulous 4{DOS,NT} interpreter, which was really a
> command-line junkie's dream.  As an example, Zsh's "AUTO_CD" feature
> is the only place I've seen 4NT's functionality mimicked (disregarding
> its actual heritage - 4NT may have stolen it from Zsh or some other
> shell), and it's *so* handy for fast touch-typists.
> 
> However, Zsh seems painfully *slow*.  I'm using a recent Cygwin
> refresh (1.3.19-1) with Zsh-4.0.6-3, and the amount of time it takes
> Zsh to complete a directory name for 'cd', for example, is painful.
> When I say it takes 2 seconds, that may not *seem* long, but when when
> I'm typing

"Time is an illusion (lunch time, doubley so)" :)

> cd /q/de<tab>/neu<tab>/emt<tab>/co<tab>/hs
> 
> and each of those <tab>s takes two seconds, I'm frustrated when I
> finally reach the end.

A dump of your env vars as well as any local vars you have set and your
zsh options might be insightful.  It might be interesting to know more
about your machine's configuration.  Speed of processor, main memory,
version of Windows, type of disk & interfaces, etc.

I, for example, run on a lowly PentiumII@400MHz, and since I'm running
WinNT 4 under an emulator (VMware), it's actually slower than that.  Even
so, I see sub-second response on my file completions. 

> The slowness is especially evident on remote drives, such as NT shares
> or (God forbid) ClearCase dynamic views (::sigh::).
> 
> Bash (2.05b-8) does not seem to suffer from this slow filename
> completion problem.  I decided to do an strace of what happens in this
> situation:
> 
> 18 13:47 /q/devtools/Neutrino/EmtPlus/vtest
> $ ls
> BAR      DIOPAT                         Ep        Per      tools
> BlueBox  DO                             HS        Summary  unittest
> Cfp      Das                            HW        Tst      zerobat_results.zip
> Com      Ddp                            IntgTest  UI       zeromem.zip
> DI       EMTPlus_descrepancy_table.doc  Lac       issues
> 
> 19 13:47 /q/devtools/Neutrino/EmtPlus/vtest
> $ cd C<tab>

You example is more that just a simple file completion in your current
directory request.  The default key mapping for TAB is
expand-or-complete.  This goes through all the aliases, and the files in
all the paths in $PATH to try and pattern match against your pattern of
"C".  If you have quite a number of aliases or a hugh PATH, this could
create quite a bit of disk I/O, trying to match against ALL of those
files.  The file matching has permutations as well (like looking for foo,
foo.exe, foo.lnk and foo.exe.lnk) which adds extra stat calls to try and
feel out if there are special variant names Zsh should be looking out for
and offers them to the user.

Try stripping your $PATH to "/usr/bin:/usr/X11R6/bin:/usr/sbin:/sbin:."
and try your completion again.

> I used strace -p <pid> to attach to the running process just before
> pressing the <tab> key; that's pretty much all I did.  Just for a
> simple comparison, look at this:
> 
> $ ls -l bash_cd.txt zsh_cd.txt
> -rw-r--r--    1 TilleJ01 mkgroup     13098 Feb 13 13:51 bash_cd.txt
> -rw-r--r--    1 TilleJ01 mkgroup    309029 Feb 13 13:00 zsh_cd.txt
> 
> Yes, Zsh's strace output is nearly *25* times larger.  Looking at the
> strace outputs more carefully, the Zsh trace has this near the
> beginning:
> 
>   117 3006802 [main] zsh 276 set_process_mask: old mask = 80000, new mask = 8000
>    98 3006900 [main] zsh 276 set_process_mask: not calling sig_dispatch_pending.
>    98 3006998 [main] zsh 276 set_process_mask: old mask = 80000, new mask = 0
>   101 3007099 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
>   314 3007413 [main] zsh 276 set_process_mask: old mask = 80000, new mask = 8000
>   106 3007519 [main] zsh 276 set_process_mask: not calling sig_dispatch_pending.
> This goes on for almost 600 lines.  Any idea what's happening here?
>
> Both shells get to the "normalize_posix_path" function *eventually*,
> but it takes bash 1 line after the keystroke read to get there,
> whereas it takes Zsh almost 600.
> 
> I sorted the strace output to get an idea of what functions where
> taking so long (except for the keyboard read, obviously).  The longest
> function called in bash takes around 10000 whatevers (usecs?).  The
> longest function called in zsh takes 25000 units!  And zsh calls 23
> functions that all take longer than the slowest bash-called function.
> 
> The long zsh functions where:
> 
> 10090 9076054 [main] zsh 276 set_process_mask: old mask = 80000, new mask = 80000
> 10106 3406991 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\DIOPAT, 632)
> 10344 9663796 [main] zsh 276 symlink_info::check: not a symlink
> 10348 3018272 [main] zsh 276 set_process_mask: old mask = 80000, new mask = 80000
> 10415 3439329 [main] zsh 276 symlink_info::check: not a symlink
> 10488 3717050 [main] zsh 276 symlink_info::check: not a symlink
> 10513 3323802 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\Com, 632)
> 10667 3365868 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\Ddp, 632)
> 10738 9445834 [main] zsh 276 symlink_info::check: not a symlink
> 12178 9128080 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
> 12606 9462770 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\EMTPlus_descrepancy_table.doc, 772)
> 12746 3456301 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\EMTPlus_descrepancy_table.doc, 632)
> 12751 9681534 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\zerobat_results.zip, 772)
> 12763 3733960 [main] zsh 276 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\vtest\zerobat_results.zip, 632)
> 14121 9060702 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
> 14212 3130669 [main] zsh 276 set_process_mask: not calling sig_dispatch_pending.  sigtid 0x674 current 0x3D8
> 14525 3002672 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
> 148890 9040940 [main] zsh 276 fhandler_tty_slave::read: reading 1 bytes (vtime 0)
> 15053 9735219 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
> 15148 3794233 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
> 20983 9810694 [main] zsh 276 dtable::dup2: dup2 (11, 0)
> 21450 3883879 [main] zsh 276 dtable::dup2: dup2 (11, 0)
> 25177 3862001 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000
> 25632 9789337 [main] zsh 276 set_process_mask: old mask = 0, new mask = 80000

The sheer number of calls is a result of Zsh trying all the various paths
to resolve the pattern to a real name.  On a typical unix system, these
are system calls and are quite fast.  However, Cygwin is an emulation
layer and thus there is extra overhead to considder.  Considder what the
performance impact is of inserting an extra functional layer to for
making a system call, then multiply that by ALL the files Zsh looks up as
well as all the variants it trys too.

> The long bash functions were:
> 
>  1022 1696574 [main] bash 1788 stat64: entering
>  1439 1674237 [main] bash 1788 normalize_posix_path: src .
>  3303 1741238 [main] bash 1788 stat64: entering
>  5198 1747773 [main] bash 1788 symlink_info::check: not a symlink
>  7243 1756457 [main] bash 1788 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\Vtest\Cfp, 880)
>  7628 1725872 [main] bash 1788 symlink_info::check: not a symlink
>  7804 1705159 [main] bash 1788 symlink_info::check: not a symlink
>  7899 1682764 [main] bash 1788 symlink_info::check: not a symlink
>  7931 1691582 [main] bash 1788 fhandler_disk_file::readdir: 0xA056704 = readdir (0xA056700) (.)
>  9678 1716326 [main] bash 1788 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\Vtest\Cfp, 880)
>  9939 1737413 [main] bash 1788 fhandler_disk_file::fstat_by_handle: 1 = GetFileInformationByHandle (q:\devtools\Neutrino\EmtPlus\Vtest\Com, 880)
> 
> You can see just *how* *much* *faster* bash is vs. zsh.  I'm sure
> something's wrong in my configuration... right?

A dump of your environment, local vars and zsh options will tell more of
the story.

> Does anyone have any ideas how I can speed up Zsh's completion?  I
> love the facilities Zsh provides, but unless I can tune it up somehow,
> it's back to bash for me.
> 
> Thanks in advance for any help.  If people suggest that I reflect this
> discussion to the Zsh User's, I'll do so.
> 
> ---Jason
> Sonos Handbell Ensemble
> http://www.sonos.org/

-- 
Peter A. Castro <doctor@fruitbat.org> or <Peter.Castro@oracle.com>
	"Cats are just autistic Dogs" -- Dr. Tony Attwood


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]