The /etc/profile script (called by default by all users’ shell startup) has the following lines:
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
This (/usr/libexec/path_helper) is a shell script which in turn has this line:
[[ "$NEWPATH" = *(*:)${p}*(:*) ]] && continue
This pattern match seems to be exponential in time complexity. When NEWPATH (derived from PATH) is around 100 characters the performance problem is neglible:
% time PATH=«100 bytes» /usr/libexec/path_helper -s
⋮
real 0m0.274s
user 0m0.264s
sys 0m0.010s
But making it 150 bytes and the problem becomes noticable:
% time PATH=«150 bytes» /usr/libexec/path_helper -s
⋮
real 0m8.313s
user 0m8.293s
sys 0m0.019s
Using 160 bytes reveals that the time complexity is indeed bad:
% time PATH=«160 bytes» /usr/libexec/path_helper -s
⋮
real 0m16.588s
user 0m16.570s
sys 0m0.015s
And just for kicks, let’s try 200 bytes:
% time PATH=«200 bytes» /usr/libexec/path_helper -s
⋮
real 4m25.442s
user 4m25.070s
sys 0m0.189s
These numbers are on a 2.66 GHz Dual-Core Intel Xeon with 3 GB RAM.
The way I generated the 200 bytes for the PATH variable was using:
% TEN=123456789:
% HUNDRED=$TEN$TEN$TEN$TEN$TEN$TEN$TEN$TEN$TEN$TEN
% time PATH=$HUNDRED$HUNDRED /usr/libexec/path_helper -s