zsh 对路径进行评估时速度很慢

zsh 对路径进行评估时速度很慢

在使用 zsh 在文件夹中执行自动完成操作时,我已经遇到性能问题相当长一段时间了。最后,我投入了一些时间来尝试了解导致问题的原因以及如何解决它。不幸的是,我不得不停在“什么”上,“如何解决”仍然是一个问号。

当在启用跟踪的情况下在调试中运行 zsh(并禁用我的.zshrc.local)时,我设法清楚地看到它:

当按双 TAB 时,执行$ cd ~/Documents/<TAB>,我得到:

....
+_cd:88> eval 'dir=( ~Documents/ )'
+(eval):1> dir=( '~Documents/' )
....

最新的响应时间约为 3 秒。

这种情况发生在文件夹自动完成的每个级别(cd a/<TAB>cd a/b/<TAB>、... ),而不是cd <TAB>.

我尝试过设置set -o magicequalsubst.

答案1

_cd当前版本中补全函数的第 88 行zsh位于仅当cdablevars启用该选项时才能到达的部分。

启用该选项后,cd username或者cd varcd进入用户的主目录username或存储的路径(如果这些用户/var存在并且当前目录或中$var没有username/目录) 。换句话说,行为就像如果不作为目录存在(在或中)。var$cdpathcd foocd ~foofoo.$cdpath

cd现在,这只是为/所做的事情pushd。当_cd构建可能的完成列表并且您Documents/到目前为止已经输入时,它需要为您提供文件夹的子目录列表Documents,而且,由于您已经启用了 ,所以还需要提供用户主目录或用户主cdablevars目录的子目录列表。变量Documents中存储的目录$Documents(如果有)。

这就是它这样做的原因eval 'dirs=( ~Documents )'

现在,我想象如果您所在的系统具有大型网络用户数据库而没有缓存(LDAP、NIS+...),那么扩展可能会很慢。zsh会在其变量列表中查找,Documents即使您有数百万个变量,因为 zsh 使用哈希表,该列表也应该很快,并调用getpwnam("Documents")以检索用户的主目录Documents,这在您的情况下可能是慢的部分。您可以通过尝试id Documents哪个应该拨打相同的getpwnam()电话来确认。

我个人会避开这个cdablevars选项,因为它肯定有一天或另一天会给你带来不好的惊喜。如果没有它,您始终可以执行cd ~useror cd ~var,并且我发现当您确实想要cd进入除作为参数给出的目录之外的其他内容时,明确请求它会更好。

cdablevars1990 年的第一个版本中就已经出现了,zsh受到tcsh默认情况下这样做的启发。它早于~var.cdablevars在我看来,应该被视为历史文物。

至于如何解决缓慢的问题getpwnam(),您可以考虑调整名称服务数据库。例如,如果使用sssd,您可以增加设置来确定在再次查询后端之前entry_negative_timeout缓存用户不存在的信息的时间。Documents对于用户数据库查询来说,3 秒似乎过多,这表明您可能存在配置问题,或者提供程序服务器不可用,并且回退机制(如果有)未以最佳方式配置。

相关内容