Skip to content

Commit 0e6c89a

Browse files
committed
tools: Add codestats.sh to compute code statistics such as size, speed.
1 parent cc20482 commit 0e6c89a

1 file changed

Lines changed: 187 additions & 0 deletions

File tree

tools/codestats.sh

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#!/bin/sh
2+
#
3+
# This script generates statistics (build size, speed) for successive
4+
# revisions of the code. It checks out git commits one an a time, compiles
5+
# various ports to determine their size, and runs pystone on the unix port.
6+
# Results are collected in the output file.
7+
#
8+
# Note: you will need to copy this file out of the tools directory before
9+
# executing because it does not exist in old revisions of the repository.
10+
11+
# check that we are in the root directory of the repository
12+
if [ ! -d py -o ! -d unix -o ! -d stmhal ]; then
13+
echo "script must be run from root of the repository"
14+
exit 1
15+
fi
16+
17+
# output file for the data; data is appended if file already exists
18+
output=codestats.dat
19+
20+
# utility programs
21+
RM=/bin/rm
22+
AWK=awk
23+
MAKE="make -j2"
24+
25+
# these are the binaries that are built; some have 2 or 3 depending on version
26+
bin_unix=unix/micropython
27+
bin_stmhal=stmhal/build-PYBV10/firmware.elf
28+
bin_barearm_1=bare-arm/build/flash.elf
29+
bin_barearm_2=bare-arm/build/firmware.elf
30+
bin_minimal=minimal/build/firmware.elf
31+
bin_cc3200_1=cc3200/build/LAUNCHXL/application.axf
32+
bin_cc3200_2=cc3200/build/LAUNCHXL/release/application.axf
33+
bin_cc3200_3=cc3200/build/WIPY/release/application.axf
34+
35+
# start at zero size; if build fails reuse previous valid size
36+
size_unix="0"
37+
size_stmhal="0"
38+
size_barearm="0"
39+
size_minimal="0"
40+
size_cc3200="0"
41+
42+
# start at zero pystones
43+
pystones="0"
44+
45+
# this code runs pystone and averages the results
46+
pystoneavg=/tmp/pystoneavg.py
47+
cat > $pystoneavg << EOF
48+
import pystone
49+
samples = [pystone.pystones(300000)[1] for i in range(5)]
50+
samples.sort()
51+
stones = sum(samples[1:-1]) / (len(samples) - 2) # exclude smallest and largest
52+
print("stones %g" % stones)
53+
EOF
54+
55+
function get_size() {
56+
if [ -r $2 ]; then
57+
size $2 | tail -n1 | $AWK '{print $1}'
58+
else
59+
echo $1
60+
fi
61+
}
62+
63+
function get_size2() {
64+
if [ -r $2 ]; then
65+
size $2 | tail -n1 | $AWK '{print $1}'
66+
elif [ -r $3 ]; then
67+
size $3 | tail -n1 | $AWK '{print $1}'
68+
else
69+
echo $1
70+
fi
71+
}
72+
73+
function get_size3() {
74+
if [ -r $2 ]; then
75+
size $2 | tail -n1 | $AWK '{print $1}'
76+
elif [ -r $3 ]; then
77+
size $3 | tail -n1 | $AWK '{print $1}'
78+
elif [ -r $4 ]; then
79+
size $4 | tail -n1 | $AWK '{print $1}'
80+
else
81+
echo $1
82+
fi
83+
}
84+
85+
# get the last revision in the data file; or start at v1.0 if no file
86+
if [ -r $output ]; then
87+
last_rev=$(tail -n1 $output | $AWK '{print $1}')
88+
else
89+
echo "# hash size_unix size_stmhal size_barearm size_minimal size_cc3200 pystones" > $output
90+
last_rev="v1.0"
91+
fi
92+
93+
# get a list of hashes between last revision (exclusive) and master
94+
hashes=$(git log --format=format:"%H" --reverse ${last_rev}..master)
95+
#hashes=$(git log --format=format:"%H" --reverse ${last_rev}..master | $AWK '{if (NR % 10 == 0) print $0}') # do every 10th one
96+
97+
for hash in $hashes; do
98+
99+
#### checkout the revision ####
100+
101+
git checkout $hash
102+
if [ $? -ne 0 ]; then
103+
echo "aborting"
104+
exit 1
105+
fi
106+
107+
#### apply patches to get it to build ####
108+
109+
if grep -q '#if defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000000) // POSIX' unix/modtime.c; then
110+
echo apply patch
111+
git apply - << EOF
112+
diff --git a/unix/modtime.c b/unix/modtime.c
113+
index 77d2945..dae0644 100644
114+
--- a/unix/modtime.c
115+
+++ b/unix/modtime.c
116+
@@ -55,10 +55,8 @@ void msec_sleep_tv(struct timeval *tv) {
117+
#define MP_CLOCKS_PER_SEC CLOCKS_PER_SEC
118+
#endif
119+
120+
-#if defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000000) // POSIX
121+
-#define CLOCK_DIV 1000.0
122+
-#elif defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000) // WIN32
123+
-#define CLOCK_DIV 1.0
124+
+#if defined(MP_CLOCKS_PER_SEC)
125+
+#define CLOCK_DIV (MP_CLOCKS_PER_SEC / 1000.0F)
126+
#else
127+
#error Unsupported clock() implementation
128+
#endif
129+
EOF
130+
fi
131+
132+
#### unix ####
133+
134+
$RM $bin_unix
135+
$MAKE -C unix CFLAGS_EXTRA=-DNDEBUG
136+
size_unix=$(get_size $size_unix $bin_unix)
137+
138+
# undo patch if it was applied
139+
git checkout unix/modtime.c
140+
141+
#### stmhal ####
142+
143+
$RM $bin_stmhal
144+
$MAKE -C stmhal board=PYBV10
145+
size_stmhal=$(get_size $size_stmhal $bin_stmhal)
146+
147+
#### bare-arm ####
148+
149+
$RM $bin_barearm_1 $bin_barearm_2
150+
$MAKE -C bare-arm
151+
size_barearm=$(get_size2 $size_barearm $bin_barearm_1 $bin_barearm_2)
152+
153+
#### minimal ####
154+
155+
if [ -r minimal/Makefile ]; then
156+
$RM $bin_minimal
157+
$MAKE -C minimal CROSS=1
158+
size_minimal=$(get_size $size_minimal $bin_minimal)
159+
fi
160+
161+
#### cc3200 ####
162+
163+
if [ -r cc3200/Makefile ]; then
164+
$RM $bin_cc3200_1 $bin_cc3200_2 $bin_cc3200_3
165+
$MAKE -C cc3200 BTARGET=application
166+
size_cc3200=$(get_size3 $size_cc3200 $bin_cc3200_1 $bin_cc3200_2 $bin_cc3200_3)
167+
fi
168+
169+
#### run pystone ####
170+
171+
if [ -x $bin_unix ]; then
172+
new_pystones=$($bin_unix $pystoneavg)
173+
# only update the variable if pystone executed successfully
174+
if echo $new_pystones | grep -q "^stones"; then
175+
pystones=$(echo $new_pystones | $AWK '{print $2}')
176+
fi
177+
fi
178+
179+
#### output data for this commit ####
180+
181+
echo "$hash $size_unix $size_stmhal $size_barearm $size_minimal $size_cc3200 $pystones" >> $output
182+
183+
done
184+
185+
# checkout master and cleanup
186+
git checkout master
187+
$RM $pystoneavg

0 commit comments

Comments
 (0)