codestats.sh 5.2 KB

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