develooper Front page | perl.perl5.porters | Postings from March 2000

Re: Code Generator + also Versioned Performance Metrics

From:
Tom Christiansen
Date:
March 29, 2000 18:38
Subject:
Re: Code Generator + also Versioned Performance Metrics
Message ID:
8626.954383890@chthon
This was eaten.  I'm trying to trick it.

To: perl5-porters@perl.org
Subject: [REPORT] Code Generator; also Versioned Performance Metrics
Reply-to: tchrist@perl.com

SUMMARY: Why can't you take perlcc and a dynamically linked libperl.so
	 to generate very small a.outs from little perl scripts anymore?

Once upon a time, one could build a /usr/bin/perl that linked against
a libperl.so to make a dramatically tinier executable: in fact, it
was only 11k.  Today, this is up to 34k, which is no big deal,
unless you count it as a 200% increase. :-)

In the table below, I show the results of running 

    perl -e 'system "ps l$$"'

through various versions of Perl, and recording the reported virtual
(VSZ) and resident (RSS) sizes.  Following that is the size of the
executable file itself (FILE), as well as the text, data, and bss
results from the size(1) command.  All figures are in rounded
kilobytes:

    PERL        VSZ   RSS   FILE  TEXT    DATA   BSS
    -------------------------------------------------
    1           168   408   152     92     36     12
    4.036       332   504   310    244     36      8
    5.003       492   652   471    384     36      0
    5.00502     552   692   532    452     32      1
    5.00503     584   692   516    484     32      1
    5.00554     616   700   599    516     32      1

    5.6.0       736   776   727    628     32      2
    5.6.0s     1244   912   989    856     44    105
    5.6.0d       88   868    34     12      4      0
    5.6.0t      792   956   773    676     32      1

The last set are all the current release.  The one marked "t" was
built with pthreads, the one marked "d" is one dynamically linked
against the libperl.so instead of against libperl.a, and the one
marked "s" was statically linked against both libc.a and libperl.a.
One is curious about where the sudden jump in size occurred.  Right
now, it's getting so Perl can barely sneeze without having to cough
up going on a megabyte.

Here are the results of my codegen adventures.  All are running a
script that does nothing more than what you saw above, save placed
in a file.  "ps.plx" is the perl source code.  "pbc" is perl bytecode
version, "pc1" is the -MO=C version, and "pc2" the -MO=CC version.


    SCRIPT      VSZ   RSS   FILE  TEXT    DATA   BSS
    -------------------------------------------------
    ps.plx      748   784     0    ---    ---    ---

    ps.pbc      992  1220   158    ---    ---    ---
    ps.pc1     1076  1084   972    756    148      0
    ps.pc2     1156  1040  1045    880     96      2

    psd.pbc     344  1340   158    ---    ---    ---
    psd.pc1     428  1188   275    140    116      0
    psd.pc2     504  1132   349    264     64      2

"psd" is used when built with a specially constructed perlcc that
knows about libperl.so.  The disk space taken up by those linked
dynamically did drop-- by about 700k--but I'd really like to konw
what the other 275-350k of it is doing there.  I used to get this
down to 20-30k, and now it's huge.  I further note that those
versions are much worse in their memory consumption than the original,
to the tune of 140%-170%.

Trying to compile these things is an incredible strain
on your C compiler.  

    C CODE          LINES   WORDS   BYTES
    --------------------------------------
    ps.pc1 src      12371   66686  633828 
    ps.pc2 src      14093   51746  493606 
    ps.pc2 src+cpp  35213  125892  912568 

Yes, that's right: the one liner turns into 35,000 lines of code
and 900k to shove through your C compiler.  

OOFDAH!

For those interested in timings, I ran some with two programs.

    1.  MEGALOOP
	    for ($i = 1; $i < 1000000; $i++) { }
    2.  TERMCAP
	    open(TC, "< /etc/termcap");
	    while (<TC>) {
		split(/:/, $_);
		for ($i = 0; $i <= $#_; $i++) { $seen{ $_[$i] }++; }
	    } 

And produced these timings.  Our loop got better, but our simple
parsing seems to have gotten worse.  The "i" version means it was
with "use integer" on the MEGALOOP test.  The others are as before.

    PERL           MEGALOOP    TERMCAP 
    ----------------------------------
    perl1           3.018       0.690
    perl4.036       2.737       0.681
    perl5.003       1.046       0.882
    perl5.00502     1.240       0.800
    perl5.00503     1.306       0.863
    perl5.00554     1.281       0.772

    perl5.6.0       1.280       0.840
    perl5.6.0i      1.437       0.871
    perl5.6.0t      1.483       1.532
    perl5.6.0d      1.864       1.159
    perl5.6i+MO=C   1.467       0.849 
    perl5.6i+MO=CC  0.785       0.803
    perl5.6i+MO=B   1.474     *COREDUMP*

The first MO=B produced one "Attempt to free unreferenced scalar",
and the coredump backtrace from the second one looks like this:

    Attempt to free unreferenced scalar, <TC> line 14703.
    Attempt to free unreferenced scalar, <TC> line 14703.
    Segmentation fault
[BACK TRACE FOLLOWS]
    #0  0x50482 in Perl_sv_free ()
    #1  0x238a1 in S_cop_free ()
    #2  0x236d9 in Perl_op_free ()
    #3  0x236a8 in Perl_op_free ()
    #4  0x236a8 in Perl_op_free ()
    #5  0x236a8 in Perl_op_free ()
    #6  0x236a8 in Perl_op_free ()
    #7  0x236a8 in Perl_op_free ()
    #8  0x236a8 in Perl_op_free ()
    #9  0x236a8 in Perl_op_free ()
    #10 0x236a8 in Perl_op_free ()
    #11 0x236a8 in Perl_op_free ()
    #12 0x236a8 in Perl_op_free ()
    #13 0x29c3 in perl_destruct ()
    #14 0x1823 in main ()

Conclusions about all this I leave to the readership.

--tom



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About