Ответ Славомира содержит ключевую часть проблемы, но без полного объяснения. Ответ на Что означает, что 'fork ()' скопирует адресное пространство исходного процесса? в Unix & Linux StackExchange имеет хороший фон.
Подстановка команд - $(...)
- реализуется путем fork()
извлечения отдельной копии вашей оболочки, в которой выполняется команда - в данном случае pwd
-.
Теперь в большинстве UNIX-подобных систем fork()
чрезвычайно эффективен и фактически не копирует всю вашу память до тех пор, пока не будет выполнена операция, которая изменит эти блоки памяти: каждая копия сохраняет одну и ту же виртуальную память диапазоны как исходные (поэтому его указатели остаются действительными), но с MMU , настроенным на выдачу ошибки при записи в нее, поэтому ОС может автоматически перехватить эту ошибку и выделить отдельную физическую память для каждой ветви .
Тем не менее, по-прежнему стоит настроить страницы, настроенные для копирования в новую физическую память при их изменении! Некоторые платформы, такие как Cygwin, имеют худшие / более дорогие реализации fork; некоторые (очевидно MacOS?) имеют более быстрые; эта разница - то, что вы измеряете здесь.
Два выноса:
Это не pwd
, это медленно, это $( )
. Это будет так же медленно с $(true)
или любой другой встроенной оболочкой, и значительно медленнее с любой не встроенной командой.
Ни в коем случае не используйте $(pwd)
- нет никакой причины платить эту цену за разделение дочернего процесса для измерения его рабочего каталога, когда вы можете просто запросить у родительской оболочки свой рабочий каталог напрямую используя nc_result=$PWD
.