123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- I measured the size of some big modules, with B::Stats and B::C, statically compiled.
- 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.
- Interestingly Module::Build is much harder to compile - you'd need 6GB RAM at least -
- and much bigger in the end-result than Moose, which compiles/compresses really fine.
- h1. Modules
- h2. Module::Build
- @perl -e'use Module::Build: print q(k)'@
- | ops | 68K |
- | files | 48 |
- | src lines | 18K |
- | compiled c lines | 1.5M |
- | perl compiler memory | 360M |
- | gcc compiler memory | **3.4G** |
- | executable size | 37M |
- h2. Moose
- | ops | 91K |
- | files | 109 |
- | src lines | 28K |
- | compiled c lines | 889K |
- | perl compiler memory | 218M |
- | gcc compiler memory | 1.6G |
- | executable size | 23M |
- h2. DateTime::TimeZone
- | ops | 2.3K |
- | files | 6 |
- | src lines | 2.2K |
- | compiled c lines | 130K |
- | perl compiler memory | 19M |
- | gcc compiler memory | 415M |
- | executable size | 32M |
- h1. Typical Apps
- h2. Biggest cPanel app
- _The recipe for less than 2MB RAM and gcc < 4.5 is:_
- cc_harness -E -o$@-cpp.c $@.c
- cc_harness -O0 -fno-var-tracking -fno-stack-protector \
- -fno-tree-loop-optimize \
- -fpreprocessed -fno-exceptions $@-cpp.c
- | ops | **467K** |
- | files | 539 |
- | src lines | 95K |
- | compiled c lines | 1.5M |
- | perl compiler memory | 352M |
- | gcc compiler memory (32bit -O0) | 2.0G |
- | executable size | **61M** |
- h2. Typical cPanel app
- | ops | 120K |
- | files | 156 |
- | src lines | 28K |
- | compiled c lines | 1M |
- | perl compiler memory | 120M |
- | gcc compiler memory (32bit -O0) | 734M |
- | executable size | 42M |
- h2. dzil --help
- | ops | 167K |
- | files | 214 |
- | src lines | 48K |
- | compiled c lines | 18M |
- | perl compiler memory | 485M |
- | gcc compiler memory | **4.5G** |
- | executable size | 48M |
- | B::C time | 182s |
- | cc time | s |
- h1. Minimal Web apps
- _A simple two-state form "like this":https://gist.github.com/387207 without Android._
- h2. Plack
- | ops | 78K |
- | files | 98 |
- | src lines | 29K |
- | compiled c lines | 388K |
- | perl compiler memory | 95M |
- | gcc compiler memory | 1.0G |
- | executable size | 11M |
- | B::C time | 11s |
- | cc time | 72s |
- h2. Dancer
- | ops | 123K |
- | files | 143 |
- | src lines | 40K |
- | compiled c lines | 517K |
- | perl compiler memory | 159M |
- | gcc compiler memory | 1.1G |
- | executable size | 14M |
- | B::C time | 20s |
- | cc time | 97s |
- h2. Mojo (daemon)
- | ops | 151K |
- | files | 150 |
- | src lines | 46K |
- | compiled c lines | 622K |
- | perl compiler memory | 153M |
- | gcc compiler memory | 1.4G |
- | executable size | 17M |
- | B::C time | 29s |
- | cc time | 114s |
- h2. Catalyst
- _catalyst.pl Catalyst::Test; script/catalyst_test_create.pl. Same numbers with the server_
- | ops | 199K |
- | files | 214 |
- | src lines | 57K |
- | compiled c lines | 941K |
- | perl compiler memory | 267M |
- | gcc compiler memory | 1.7G |
- | executable size | 26M |
- | B::C time | 44s |
- | cc time | 169s |
- h1. Minimal OO frameworks
- h2. Moose
- | ops | 91K |
- | files | 109 |
- | src lines | 28K |
- | compiled c lines | 889K |
- | perl compiler memory | 218M |
- | gcc compiler memory | 1.6G |
- | executable size | 23M |
- h2. Mouse
- | ops | 20K |
- | files | 23 |
- | src lines | 6.5K |
- | compiled c lines | 120K |
- | perl compiler memory | 19M |
- | gcc compiler memory | 427M |
- | executable size | 3.3M |
- h2. Moo
- | ops | 6.4K |
- | files | 16 |
- | src lines | 3.7K |
- | compiled c lines | 96K |
- | perl compiler memory | 17M |
- | gcc compiler memory | _error_ (326M) |
- | executable size | _error_ (2.7M) |
- h2. Mo
- | ops | 3.7K |
- | files | 8 |
- | src lines | 2.6K |
- | compiled c lines | 67K |
- | perl compiler memory | - _(too tiny, not measurable)_ |
- | gcc compiler memory | 346M |
- | executable size | 1.8M |
- h1. Summary
- 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.
- Moose alone is okay to use, dzil for sure not.
- A minimal web app with Plack, Dancer, Mojo and even Catalyst look all okay.
- SW metrics to explain the style, why the numbers are so different in the next blog post.
- 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.
- Measured numbers are for x86_64 perl5.14.2-nt, gcc -Os -msse4.2 -march=corei7
- | | | gcc | c | exe |
- | | subs | mem[M] | lines | size |
- | Dist::Zilla | 4309 | 4500 | 1320K | 46M |
- | Module::Build | 4017 | 3400 | 1500K | 37M |
- | CPAN | 4142 | 3300 | 1319K | 33M |
- | Catalyst | 4508 | 1700 | 941K | 26M |
- | ExtUtils::CBuilder | 1633 | 1552 | 595K | 15M |
- | Moose | 2523 | 1600 | 889K | 23M |
- | Mojo | 2559 | 1400 | 622K | 17M |
- | Dancer | 2368 | 1100 | 517K | 14M |
- | Plack | 1945 | 1000 | 388K | 11M |
- | ExtUtils::MakeMaker | 1233 | 957 | 335K | 8.4M |
- | DateTime | 1277 | 840 | 293K | 6.8M |
- | DateTime::TimeZone | 542 | 415 | 130K | 3.1M |
- | DateTime::Locale | 471 | 464 | 138K | 3.4M |
- | Mouse | 743 | 427 | 120K | 3.3M |
- | Moo | 572 | 326 | 96K | 2.7M |
- | Mo | 388 | 346 | 67K | 1.8M |
- h1. Makefile tricks
- If you want to check in your Makefile how much memory is available and
- disable some gcc optimizations accordingly you can something like this:
- Makefile snippet
- bc. AVAILMEM=$(shell availmem.sh)
- bigapp: $@.pl
- if [ ${AVAILMEM} -lt 2000000 ]; then \
- echo "less than 2GB free RAM, disable some gcc optimizations"; \
- /bin/rm -f $@ $@-cpp.c $@.c; \
- perl -c $@.pl; \
- perl -MO=C,-O3,-o$@.c $@.pl; \
- cc_harness -E -o$@-cpp.c $@.c; \
- cc_harness -O0 -fno-var-tracking -fno-stack-protector \
- -fno-tree-loop-optimize -fpreprocessed \
- -fno-exceptions $@-cpp.c -o$@; \
- /bin/rm -f $@-cpp.c $@.c; \
- else \
- perlcc $(PERLCC_OPTS) $@.pl -o $@; \
- fi
- My availmem.sh on linux:
- bc. #!/bin/sh
- memtotal=$(perl -ane'print $F[1] if /^MemTotal:/' /proc/meminfo)
- memused=$(perl -ane'print $F[1] if /^Active:/' /proc/meminfo)
- echo $(($memtotal - $memused))
- Plack
- p -MB::Stats t/plack.pl
- pb script/perlcc -v2 --time -O3 t/plack.pl -S -ot/plack
- files=98 lines=28891 ops=78214
- perl res 95m
- cc1 res 1.0g
- c time: 11.407679
- cc time: 71.652737
- Dancer
- p -MB::Stats t/dancer.pl
- pb script/perlcc -v2 --time -O3 -S t/dancer.pl
- files=143 lines=40177 ops=123197
- perl res 159m
- cc1 res 1.1g
- c time: 20.45
- cc time: 96.88
- Mojo
- (daemon)
- files=150 lines=46779 ops=151577
- perl res 153m
- cc1 res 1.4g
- c 29s
- cc 114s
- Catalyst
- script/catalyst_test_create.pl (no server)
- files=214 lines=57770 ops=199103
- perl res 267m
- cc1 res 1.7g
- c time: 44s
- cc time: 169s
- CPAN
- c time: 78.491689
- cc time: 255.88538
- mouse
- pb script/perlcc -v2 --time -O3 -S -ot/mouse -e'use Mouse; print q(ok)'
- 19m
- 427m
- c time: 2.758865
- cc time: 23.37078
- number of subs:
- for m in Module::Build Moose Mouse Moo Mo DateTime::TimeZone Dist::Zilla Plack::Runner;use Plack::Request Dancer Mojo Catalyst
- do
- echo -n "$m ";
- perlcc -v4 --Wb=-Ds,-c -e'use Moose' 2>&1 |egrep -iv "^ (New |Warning)"|sort -u|wc -l
- echo "";
- done
- gcc c exe
- subs mem[M] lines size
- Dist::Zilla 4309 4500 18000K 48M
- Module::Build 4017 3400 1500K 37M
- CPAN 4142 3300 1319K 33M
- Catalyst 4508 1700 941K 26M
- ExtUtils::CBuilder 1633 1552 595K 15M
- Moose 2523 1600 889K 23M
- Mojo 2559 1400 622K 17M
- Dancer 2368 1100 517K 14M
- Plack 1945 1000 388K 11M
- ExtUtils::MakeMaker 1233 957 335K 8.4M
- DateTime 1277 840 293K 6.8M
- DateTime::TimeZone 542 415 130K 3.1M
- DateTime::Locale 471 464 138K 3.4M
- Mouse 743 427 120K 3.3M
- Moo 572 326 96K 2.7M
- Mo 388 346 67K 1.8M
|