Some tips to speed-up scripts... Add yours, and put the better ones on the top of the page :) ==== Sed substitution vs Variable substitution ==== **Information** In some cases, both tools can do the same job. As a built-in ash/bash command, variable substitution is faster. Note: this is always true - you can compare each type of variable substitution with an equivalent using an external tool. **Benchmark** $ echo '#!/bin/sh for i in $(seq 1 1000); do echo "slitaz" | sed 's/slitaz/SliTaz/' done' > /tmp/slow $ echo '#!/bin/sh for i in $(seq 1 1000); do A=slitaz echo "${A/slitaz/SliTaz}" done' > /tmp/speed $ chmod +x /tmp/slow /tmp/speed $ time /tmp/slow > real 0m 12.40s $ time /tmp/speed > real 0m 0.04s ==== Group command vs. Sub-process ==== **Information** Group command "{}" groups several commands into one (as a function). So, output can be grouped too: "{ com1; com2; } | com3". Sub-process "()" achieves something similar, but creates a shell sub-process; which costs a lot more resources. Another difference is that when you kill an application using CTRL^C, a sub-process is killed instead of a main application - while CTRL^C on grouped commands kills the application itself. Finally, changing directory or variables into sub-processes will not affect the main script which it does with grouped commands. Conclusion: always use group commands instead of sub-processes, and take care ;D //Note:// group commands need a newline before closing - or "; }". **Benchmark** $ echo '#!/bin/sh for i in $(seq 1 10000); do ( echo yo ) done' > /tmp/slow $ echo '#!/bin/sh for i in $(seq 1 10000); do { echo yo; } done' > /tmp/speed $ chmod +x /tmp/slow /tmp/speed $ time /tmp/slow > real 0m 5.36s $ time /tmp/speed > real 0m 0.23s ==== Grep vs Fgrep ==== **Information** fgrep is exactly the same thing as grep if you don't use patterns (^,$,*,etc.). Fgrep is optimized to handle such cases, particularly when you look for several different plain patterns. A difference can be found even if you look in only one pattern. **Benchmark** $ echo -e "line1\nline2\nline3" > /tmp/file $ echo '#!/bin/sh for i in $(seq 1 1000); do grep 3 /tmp/file done' > /tmp/slow $ echo '#!/bin/sh for i in $(seq 1 1000); do fgrep 3 /tmp/file done' > /tmp/speed $ chmod +x /tmp/slow /tmp/speed $ time /tmp/slow > real 0m 11.87s $ time /tmp/speed > real 0m 3.21s ==== [ -n "text" ] vs [ "text" ] ==== **Information** The two commands test if "text" exists. Using -n slows the process and weighs down the script a little too. **Benchmark** $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ -n "$i" ] done' > /tmp/slow $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ "$i" ] done' > /tmp/speed $ chmod +x /tmp/slow /tmp/speed $ time /tmp/slow > real 0m 15.56s $ time /tmp/speed > real 0m 14.11s ==== [ -z "text" ] vs [ ! "text" ] vs ! [ "text" ] ==== **Information** These three commands test if text **doesn't** exist. [ ! "text" ] and [ -z "text" ] have a similar processing time, while ! [ "text" ] is speedier. **Benchmark** $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ -n "$i" ] done' > /tmp/slow1 $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ -n "$i" ] done' > /tmp/slow2 $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ "$i" ] done' > /tmp/speed $ chmod +x /tmp/slow1 /tmp/slow2 /tmp/speed $ time /tmp/slow1 > real 0m 15.53s $ time /tmp/slow2 > real 0m 15.60s $ time /tmp/speed > real 0m 14.27s ==== Awk vs Cut ==== **Information** Awk, as cut, can be used to cut a field of a line. Awk can do many other things, while cut is a tool dedicated to this usage; it's why cut is a little faster for this task. **Benchmark** $ echo -e "field1\tfield2\tfield3" > /tmp/file $ echo '#!/bin/sh for i in $(seq 1 5000); do awk '"'"'{ print $2 }'"'"' /tmp/file done' > /tmp/slow $ echo '#!/bin/sh for i in $(seq 5000); do cut -f2 /tmp/file done' > /tmp/speed $ chmod +x /tmp/slow /tmp/speed $ time /tmp/slow > real 0m 16.61s $ time /tmp/speed > real 0m 15.90s ==== [ condition1 -a condition2 ] vs [ condition1 ] && [ condition2 ] ==== **Information** While && is a fast built-in function, in this case it uses two processes (two test functions) instead of one. So, using -a is a little faster, as the "AND" function itself is slower but makes it possible to use only one process. **Benchmark** $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ "$i" ] && [ "$i" ] done' > /tmp/slow $ echo '#!/bin/sh for i in $(seq 1 1000000); do [ "$i" -a "$i" ] done' > /tmp/speed $ chmod +x /tmp/slow /tmp/speed $ time /tmp/slow > real 0m 23.94s $ time /tmp/speed > real 0m 22.29s