I wrote:
>It would be possible to use a more efficient approach when the pattern
>is known to have no special characters. But that would require more
>code.
To quantify this I made a patch which handles the special case of
patterns that don't require globbing. The feature is controlled by
the ASH_OPTIMIZE_FOR_SIZE configuration option so it isn't enabled
in the default build (where ASH_OPTIMIZE_FOR_SIZE is enabled).
When it is enabled it adds 183 bytes.
Benchmarks with the feature enabled follow. This command uses a
bracket expression so globbing is required:
hyperfine -L n 10,15,20,30 -S ./ash -w 2 -r 10 -s basic '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -{n});
for i in $(seq 1 20); do echo "${x//[:]/|}"; done'
Benchmark #1:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -10);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done
Time (mean ± σ): 36.9 ms ± 0.6 ms [User: 36.3 ms, System: 1.1 ms]
Range (min … max): 36.2 ms … 38.4 ms 10 runs
Benchmark #2:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -15);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done
Time (mean ± σ): 104.6 ms ± 1.4 ms [User: 104.0 ms, System: 1.0 ms]
Range (min … max): 103.1 ms … 107.6 ms 10 runs
Benchmark #3:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -20);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done
Time (mean ± σ): 241.3 ms ± 2.7 ms [User: 240.5 ms, System: 1.1 ms]
Range (min … max): 238.2 ms … 246.7 ms 10 runs
Benchmark #4:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -30);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done
Time (mean ± σ): 697.1 ms ± 4.0 ms [User: 695.6 ms, System: 1.0 ms]
Range (min … max): 691.8 ms … 701.8 ms 10 runs
Summary
'
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -10);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done' ran
2.84 ± 0.06 times faster than '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -15);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done'
6.54 ± 0.14 times faster than '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -20);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done'
18.90 ± 0.35 times faster than '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -30);
for i in $(seq 1 20); do echo "${x//[:]/|}"; done'
The elapsed times and the increase in time with variable length are
similar to the results reported previously.
This command uses a literal search string:
hyperfine -L n 10,15,20,30 -S ./ash -w 2 -r 10 -s basic '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -{n});
for i in $(seq 1 1000); do echo "${x//:/|}"; done'
Benchmark #1:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -10);
for i in $(seq 1 1000); do echo "${x//:/|}"; done
Time (mean ± σ): 9.0 ms ± 0.6 ms [User: 8.4 ms, System: 1.2 ms]
Range (min … max): 8.5 ms … 10.5 ms 10 runs
Benchmark #2:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -15);
for i in $(seq 1 1000); do echo "${x//:/|}"; done
Time (mean ± σ): 12.5 ms ± 0.1 ms [User: 11.6 ms, System: 1.5 ms]
Range (min … max): 12.4 ms … 12.7 ms 10 runs
Benchmark #3:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -20);
for i in $(seq 1 1000); do echo "${x//:/|}"; done
Time (mean ± σ): 17.9 ms ± 1.1 ms [User: 17.6 ms, System: 0.9 ms]
Range (min … max): 17.0 ms … 19.5 ms 10 runs
Benchmark #4:
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -30);
for i in $(seq 1 1000); do echo "${x//:/|}"; done
Time (mean ± σ): 27.2 ms ± 0.9 ms [User: 26.7 ms, System: 1.1 ms]
Range (min … max): 26.0 ms … 28.4 ms 10 runs
Summary
'
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -10);
for i in $(seq 1 1000); do echo "${x//:/|}"; done' ran
1.39 ± 0.09 times faster than '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -15);
for i in $(seq 1 1000); do echo "${x//:/|}"; done'
1.99 ± 0.18 times faster than '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -20);
for i in $(seq 1 1000); do echo "${x//:/|}"; done'
3.03 ± 0.22 times faster than '
x=$(cat /etc/passwd /etc/passwd /etc/passwd | head -30);
for i in $(seq 1 1000); do echo "${x//:/|}"; done'
The elapsed times are much shorter: I had to increase the number of
iterations from 20 to 1000 to get reliable measurements. The increase
in time with variable length is linear.
Ron
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox