加载大文件(例如:40M)后,“ pwd”命令会花费大量时间

时间:2019-07-01 16:01:21

标签: bash

以下测试shell代码在以下位置进行测试:具有bash shell的centOS 7;该代码包含三个短语;短语1,调用pwd命令;短语2,读取一个大文件(猫文件);短语3与短语1相同;

短语3的时间成本比短语1更大(例如:21s vs 7s)

但是在MacOS平台上,词组1和词组3的时间成本相等。     #!/ bin / bash

#phrase 1
timeStart1=$(date +%s)
for ((ip=1;ip<=10000;ip++));
do
nc_result=$(pwd)
done
timeEnd1=$(date +%s)
timeDelta=$((timeEnd1-timeStart1))

echo $timeDelta

#phrase 2
fileName='./content.txt'   #one big file,eg. a 39M file
content=`cat $fileName`

#phrase 3
timeStart2=$(date +%s)
for ((ip=1;ip<=10000;ip++));
do
nc_result=$(pwd)
done
timeEnd2=$(date +%s)
timeDelta2=$((timeEnd2-timeStart2))
echo $timeDelta2

2 个答案:

答案 0 :(得分:1)

Slawomir's answer是问题的关键部分,但没有完整的解释。 What does it mean 'fork()' will copy address space of original process?上的Unix & Linux StackExchange的答案有一定的背景。

命令替换-$(...)-通过fork()剥离外壳的单独副本来实现,该命令在本例中为pwd的执行

现在,在大多数 类似于UNIX的系统上,fork()非常高效,并且在执行更改这些内存块的操作之前,它实际上不会复制所有内存:每个副本都保留虚拟内存范围与原始虚拟内存范围相同(因此其指针保持有效),但是将MMU配置为在写入数据时抛出错误,因此OS可以静默捕获该错误并为每个错误分配单独的物理内存分支。

尽管如此,设置配置为在更改时将其复制到新物理内存中的页面仍存在成本!一些平台(例如Cygwin)具有更差/更昂贵的fork实现;一些(显然是MacOS?)具有更快的速度;那就是您要在此处测量的差异。


两个要点:

  • 不是pwd慢,而是$( )。使用$(true)或其他任何内置Shell的速度都一样慢,而使用任何非内置命令的速度要慢得多

  • 根本不使用$(pwd) -当您只需要向父shell询问其工作目录时,就没有理由为此花费费用来拆分一个子进程来测量其工作目录直接使用nc_result=$PWD

答案 1 :(得分:0)

$()调用一个子shell。当第二条命令运行时,第三条命令开始。