slitaz-doc-wiki-data view pages/en/devnotes/ash-benchmarks.txt @ rev 15

Updated pages on 2011-03-11.
author Christopher Rogers <slaxemulator@gmail.com>
date Fri Mar 11 14:19:17 2011 +0000 (2011-03-11)
parents 70b5f3ae5339
children
line source
1 Some tips to speed-up scripts... Add yours, and put the better ones on the top of the page :)
3 ==== Sed substitution vs Variable substitution ====
5 **Information**
7 In some cases, both tools can do the same job. As a built-in ash/bash command, variable substitution is faster.
8 Note: this is always true - you can compare each type of variable substitution with an equivalent using an external tool.
10 **Benchmark**
11 <code>
12 $ echo '#!/bin/sh
13 for i in $(seq 1 1000); do
14 echo "slitaz" | sed 's/slitaz/SliTaz/'
15 done' > /tmp/slow
16 $ echo '#!/bin/sh
17 for i in $(seq 1 1000); do
18 A=slitaz
19 echo "${A/slitaz/SliTaz}"
20 done' > /tmp/speed
21 $ chmod +x /tmp/slow /tmp/speed
22 $ time /tmp/slow
23 > real 0m 12.40s
24 $ time /tmp/speed
25 > real 0m 0.04s
26 </code>
28 ==== Group command vs. Sub-process ====
30 **Information**
32 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
34 //Note:// group commands need a newline before closing - or "; }".
36 **Benchmark**
37 <code>
38 $ echo '#!/bin/sh
39 for i in $(seq 1 10000); do
40 ( echo yo )
41 done' > /tmp/slow
42 $ echo '#!/bin/sh
43 for i in $(seq 1 10000); do
44 { echo yo; }
45 done' > /tmp/speed
46 $ chmod +x /tmp/slow /tmp/speed
47 $ time /tmp/slow
48 > real 0m 5.36s
49 $ time /tmp/speed
50 > real 0m 0.23s
51 </code>
53 ==== Grep vs Fgrep ====
55 **Information**
57 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.
59 **Benchmark**
60 <code>
61 $ echo -e "line1\nline2\nline3" > /tmp/file
62 $ echo '#!/bin/sh
63 for i in $(seq 1 1000); do
64 grep 3 /tmp/file
65 done' > /tmp/slow
66 $ echo '#!/bin/sh
67 for i in $(seq 1 1000); do
68 fgrep 3 /tmp/file
69 done' > /tmp/speed
70 $ chmod +x /tmp/slow /tmp/speed
71 $ time /tmp/slow
72 > real 0m 11.87s
73 $ time /tmp/speed
74 > real 0m 3.21s
75 </code>
77 ==== [ -n "text" ] vs [ "text" ] ====
79 **Information**
81 The two commands test if "text" exists. Using -n slows the process and weighs down the script a little too.
83 **Benchmark**
84 <code>
85 $ echo '#!/bin/sh
86 for i in $(seq 1 1000000); do
87 [ -n "$i" ]
88 done' > /tmp/slow
89 $ echo '#!/bin/sh
90 for i in $(seq 1 1000000); do
91 [ "$i" ]
92 done' > /tmp/speed
93 $ chmod +x /tmp/slow /tmp/speed
94 $ time /tmp/slow
95 > real 0m 15.56s
96 $ time /tmp/speed
97 > real 0m 14.11s
98 </code>
100 ==== [ -z "text" ] vs [ ! "text" ] vs ! [ "text" ] ====
102 **Information**
104 These three commands test if text **doesn't** exist. [ ! "text" ] and [ -z "text" ] have a similar processing time, while ! [ "text" ] is speedier.
106 **Benchmark**
107 <code>
108 $ echo '#!/bin/sh
109 for i in $(seq 1 1000000); do
110 [ -n "$i" ]
111 done' > /tmp/slow1
112 $ echo '#!/bin/sh
113 for i in $(seq 1 1000000); do
114 [ -n "$i" ]
115 done' > /tmp/slow2
116 $ echo '#!/bin/sh
117 for i in $(seq 1 1000000); do
118 [ "$i" ]
119 done' > /tmp/speed
120 $ chmod +x /tmp/slow1 /tmp/slow2 /tmp/speed
121 $ time /tmp/slow1
122 > real 0m 15.53s
123 $ time /tmp/slow2
124 > real 0m 15.60s
125 $ time /tmp/speed
126 > real 0m 14.27s
127 </code>
129 ==== Awk vs Cut ====
131 **Information**
133 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.
135 **Benchmark**
136 <code>
137 $ echo -e "field1\tfield2\tfield3" > /tmp/file
138 $ echo '#!/bin/sh
139 for i in $(seq 1 5000); do
140 awk '"'"'{ print $2 }'"'"' /tmp/file
141 done' > /tmp/slow
142 $ echo '#!/bin/sh
143 for i in $(seq 5000); do
144 cut -f2 /tmp/file
145 done' > /tmp/speed
146 $ chmod +x /tmp/slow /tmp/speed
147 $ time /tmp/slow
148 > real 0m 16.61s
149 $ time /tmp/speed
150 > real 0m 15.90s
151 </code>
153 ==== [ condition1 -a condition2 ] vs [ condition1 ] && [ condition2 ] ====
155 **Information**
157 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.
159 **Benchmark**
160 <code>
161 $ echo '#!/bin/sh
162 for i in $(seq 1 1000000); do
163 [ "$i" ] && [ "$i" ]
164 done' > /tmp/slow
165 $ echo '#!/bin/sh
166 for i in $(seq 1 1000000); do
167 [ "$i" -a "$i" ]
168 done' > /tmp/speed
169 $ chmod +x /tmp/slow /tmp/speed
170 $ time /tmp/slow
171 > real 0m 23.94s
172 $ time /tmp/speed
173 > real 0m 22.29s
174 </code>