module-sizes 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. I measured the size of some big modules, with B::Stats and B::C, statically compiled.
  2. This amounts to about to the same size as dynamic usage via perl, with all options and modules used at once. I.e. the worst-case scenario.
  3. Interestingly Module::Build is much harder to compile - you'd need 6GB RAM at least -
  4. and much bigger in the end-result than Moose, which compiles/compresses really fine.
  5. h1. Modules
  6. h2. Module::Build
  7. @perl -e'use Module::Build: print q(k)'@
  8. | ops | 68K |
  9. | files | 48 |
  10. | src lines | 18K |
  11. | compiled c lines | 1.5M |
  12. | perl compiler memory | 360M |
  13. | gcc compiler memory | **3.4G** |
  14. | executable size | 37M |
  15. h2. Moose
  16. | ops | 91K |
  17. | files | 109 |
  18. | src lines | 28K |
  19. | compiled c lines | 889K |
  20. | perl compiler memory | 218M |
  21. | gcc compiler memory | 1.6G |
  22. | executable size | 23M |
  23. h2. DateTime::TimeZone
  24. | ops | 2.3K |
  25. | files | 6 |
  26. | src lines | 2.2K |
  27. | compiled c lines | 130K |
  28. | perl compiler memory | 19M |
  29. | gcc compiler memory | 415M |
  30. | executable size | 32M |
  31. h1. Typical Apps
  32. h2. Biggest cPanel app
  33. _The recipe for less than 2MB RAM and gcc < 4.5 is:_
  34. cc_harness -E -o$@-cpp.c $@.c
  35. cc_harness -O0 -fno-var-tracking -fno-stack-protector \
  36. -fno-tree-loop-optimize \
  37. -fpreprocessed -fno-exceptions $@-cpp.c
  38. | ops | **467K** |
  39. | files | 539 |
  40. | src lines | 95K |
  41. | compiled c lines | 1.5M |
  42. | perl compiler memory | 352M |
  43. | gcc compiler memory (32bit -O0) | 2.0G |
  44. | executable size | **61M** |
  45. h2. Typical cPanel app
  46. | ops | 120K |
  47. | files | 156 |
  48. | src lines | 28K |
  49. | compiled c lines | 1M |
  50. | perl compiler memory | 120M |
  51. | gcc compiler memory (32bit -O0) | 734M |
  52. | executable size | 42M |
  53. h2. dzil --help
  54. | ops | 167K |
  55. | files | 214 |
  56. | src lines | 48K |
  57. | compiled c lines | 18M |
  58. | perl compiler memory | 485M |
  59. | gcc compiler memory | **4.5G** |
  60. | executable size | 48M |
  61. | B::C time | 182s |
  62. | cc time | s |
  63. h1. Minimal Web apps
  64. _A simple two-state form "like this":https://gist.github.com/387207 without Android._
  65. h2. Plack
  66. | ops | 78K |
  67. | files | 98 |
  68. | src lines | 29K |
  69. | compiled c lines | 388K |
  70. | perl compiler memory | 95M |
  71. | gcc compiler memory | 1.0G |
  72. | executable size | 11M |
  73. | B::C time | 11s |
  74. | cc time | 72s |
  75. h2. Dancer
  76. | ops | 123K |
  77. | files | 143 |
  78. | src lines | 40K |
  79. | compiled c lines | 517K |
  80. | perl compiler memory | 159M |
  81. | gcc compiler memory | 1.1G |
  82. | executable size | 14M |
  83. | B::C time | 20s |
  84. | cc time | 97s |
  85. h2. Mojo (daemon)
  86. | ops | 151K |
  87. | files | 150 |
  88. | src lines | 46K |
  89. | compiled c lines | 622K |
  90. | perl compiler memory | 153M |
  91. | gcc compiler memory | 1.4G |
  92. | executable size | 17M |
  93. | B::C time | 29s |
  94. | cc time | 114s |
  95. h2. Catalyst
  96. _catalyst.pl Catalyst::Test; script/catalyst_test_create.pl. Same numbers with the server_
  97. | ops | 199K |
  98. | files | 214 |
  99. | src lines | 57K |
  100. | compiled c lines | 941K |
  101. | perl compiler memory | 267M |
  102. | gcc compiler memory | 1.7G |
  103. | executable size | 26M |
  104. | B::C time | 44s |
  105. | cc time | 169s |
  106. h1. Minimal OO frameworks
  107. h2. Moose
  108. | ops | 91K |
  109. | files | 109 |
  110. | src lines | 28K |
  111. | compiled c lines | 889K |
  112. | perl compiler memory | 218M |
  113. | gcc compiler memory | 1.6G |
  114. | executable size | 23M |
  115. h2. Mouse
  116. | ops | 20K |
  117. | files | 23 |
  118. | src lines | 6.5K |
  119. | compiled c lines | 120K |
  120. | perl compiler memory | 19M |
  121. | gcc compiler memory | 427M |
  122. | executable size | 3.3M |
  123. h2. Moo
  124. | ops | 6.4K |
  125. | files | 16 |
  126. | src lines | 3.7K |
  127. | compiled c lines | 96K |
  128. | perl compiler memory | 17M |
  129. | gcc compiler memory | _error_ (326M) |
  130. | executable size | _error_ (2.7M) |
  131. h2. Mo
  132. | ops | 3.7K |
  133. | files | 8 |
  134. | src lines | 2.6K |
  135. | compiled c lines | 67K |
  136. | perl compiler memory | - _(too tiny, not measurable)_ |
  137. | gcc compiler memory | 346M |
  138. | executable size | 1.8M |
  139. h1. Summary
  140. If you compile an app like Module::Build, i.e dzil (which means in the convoluted java-like style like Module::Build) you need a really big build machine, and developers will not be able to compile it by themselves, because they have not enough RAM. Errors will only appear daily (from the build machine), not immediately.
  141. Moose alone is okay to use, dzil for sure not.
  142. A minimal web app with Plack, Dancer, Mojo and even Catalyst look all okay.
  143. SW metrics to explain the style, why the numbers are so different in the next blog post.
  144. So if you plan to do "modern perl" you'll either take care, like using Mouse or Moo, or do something like prefork or FCGI and do not care.
  145. Measured numbers are for x86_64 perl5.14.2-nt, gcc -Os -msse4.2 -march=corei7
  146. | | | gcc | c | exe |
  147. | | subs | mem[M] | lines | size |
  148. | Dist::Zilla | 4309 | 4500 | 1320K | 46M |
  149. | Module::Build | 4017 | 3400 | 1500K | 37M |
  150. | CPAN | 4142 | 3300 | 1319K | 33M |
  151. | Catalyst | 4508 | 1700 | 941K | 26M |
  152. | ExtUtils::CBuilder | 1633 | 1552 | 595K | 15M |
  153. | Moose | 2523 | 1600 | 889K | 23M |
  154. | Mojo | 2559 | 1400 | 622K | 17M |
  155. | Dancer | 2368 | 1100 | 517K | 14M |
  156. | Plack | 1945 | 1000 | 388K | 11M |
  157. | ExtUtils::MakeMaker | 1233 | 957 | 335K | 8.4M |
  158. | DateTime | 1277 | 840 | 293K | 6.8M |
  159. | DateTime::TimeZone | 542 | 415 | 130K | 3.1M |
  160. | DateTime::Locale | 471 | 464 | 138K | 3.4M |
  161. | Mouse | 743 | 427 | 120K | 3.3M |
  162. | Moo | 572 | 326 | 96K | 2.7M |
  163. | Mo | 388 | 346 | 67K | 1.8M |
  164. h1. Makefile tricks
  165. If you want to check in your Makefile how much memory is available and
  166. disable some gcc optimizations accordingly you can something like this:
  167. Makefile snippet
  168. bc. AVAILMEM=$(shell availmem.sh)
  169. bigapp: $@.pl
  170. if [ ${AVAILMEM} -lt 2000000 ]; then \
  171. echo "less than 2GB free RAM, disable some gcc optimizations"; \
  172. /bin/rm -f $@ $@-cpp.c $@.c; \
  173. perl -c $@.pl; \
  174. perl -MO=C,-O3,-o$@.c $@.pl; \
  175. cc_harness -E -o$@-cpp.c $@.c; \
  176. cc_harness -O0 -fno-var-tracking -fno-stack-protector \
  177. -fno-tree-loop-optimize -fpreprocessed \
  178. -fno-exceptions $@-cpp.c -o$@; \
  179. /bin/rm -f $@-cpp.c $@.c; \
  180. else \
  181. perlcc $(PERLCC_OPTS) $@.pl -o $@; \
  182. fi
  183. My availmem.sh on linux:
  184. bc. #!/bin/sh
  185. memtotal=$(perl -ane'print $F[1] if /^MemTotal:/' /proc/meminfo)
  186. memused=$(perl -ane'print $F[1] if /^Active:/' /proc/meminfo)
  187. echo $(($memtotal - $memused))
  188. Plack
  189. p -MB::Stats t/plack.pl
  190. pb script/perlcc -v2 --time -O3 t/plack.pl -S -ot/plack
  191. files=98 lines=28891 ops=78214
  192. perl res 95m
  193. cc1 res 1.0g
  194. c time: 11.407679
  195. cc time: 71.652737
  196. Dancer
  197. p -MB::Stats t/dancer.pl
  198. pb script/perlcc -v2 --time -O3 -S t/dancer.pl
  199. files=143 lines=40177 ops=123197
  200. perl res 159m
  201. cc1 res 1.1g
  202. c time: 20.45
  203. cc time: 96.88
  204. Mojo
  205. (daemon)
  206. files=150 lines=46779 ops=151577
  207. perl res 153m
  208. cc1 res 1.4g
  209. c 29s
  210. cc 114s
  211. Catalyst
  212. script/catalyst_test_create.pl (no server)
  213. files=214 lines=57770 ops=199103
  214. perl res 267m
  215. cc1 res 1.7g
  216. c time: 44s
  217. cc time: 169s
  218. CPAN
  219. c time: 78.491689
  220. cc time: 255.88538
  221. mouse
  222. pb script/perlcc -v2 --time -O3 -S -ot/mouse -e'use Mouse; print q(ok)'
  223. 19m
  224. 427m
  225. c time: 2.758865
  226. cc time: 23.37078
  227. number of subs:
  228. for m in Module::Build Moose Mouse Moo Mo DateTime::TimeZone Dist::Zilla Plack::Runner;use Plack::Request Dancer Mojo Catalyst
  229. do
  230. echo -n "$m ";
  231. perlcc -v4 --Wb=-Ds,-c -e'use Moose' 2>&1 |egrep -iv "^ (New |Warning)"|sort -u|wc -l
  232. echo "";
  233. done
  234. gcc c exe
  235. subs mem[M] lines size
  236. Dist::Zilla 4309 4500 18000K 48M
  237. Module::Build 4017 3400 1500K 37M
  238. CPAN 4142 3300 1319K 33M
  239. Catalyst 4508 1700 941K 26M
  240. ExtUtils::CBuilder 1633 1552 595K 15M
  241. Moose 2523 1600 889K 23M
  242. Mojo 2559 1400 622K 17M
  243. Dancer 2368 1100 517K 14M
  244. Plack 1945 1000 388K 11M
  245. ExtUtils::MakeMaker 1233 957 335K 8.4M
  246. DateTime 1277 840 293K 6.8M
  247. DateTime::TimeZone 542 415 130K 3.1M
  248. DateTime::Locale 471 464 138K 3.4M
  249. Mouse 743 427 120K 3.3M
  250. Moo 572 326 96K 2.7M
  251. Mo 388 346 67K 1.8M