Subject: Re: Writing shared libraries using Lisp
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 13 Jul 2005 00:15:59 -0500
Newsgroups: comp.lang.lisp
Message-ID: <-MGdnRHIu-ISPknfRVn-rA@speakeasy.net>
Juanjo <worm@arrakis.es> wrote:
+---------------
| ECL (http://ecls.sf.net) is a Common-Lisp environment which, apart from
| having a bytecodes interpreter and compiler, can compile lisp to C and
| produce native standalone executables, shared libraries and loadable
| modules. This functionality is supported in Windows, Linux, FreeBSD,
| NetBSD and Mac OSX.
+---------------

I've just started playing with ECL, and some parts of it are certainly
very interesting, especially how small simple compiled CL programs are.
But I've discovered that it has one major downside for the kind of "Lisp
scripting" I often do, namely, even with a very small executable and only
a single sharable library for the bulk of the system, it seems to take a
*loooooonnngg* time to start up. Example:

    $ cat hello.lisp
    (princ "Hello world!")
    (terpri)
    (quit)
    $ ls -lt hello.c hello.o hello  # intermediate & final compiled outputs
    -rw-r--r-- 1 rpw3 rpw3  1036 Jun 29 20:49 hello.c
    -rw-r--r-- 1 rpw3 rpw3 18984 Jun 29 20:49 hello.o
    -rwxr-xr-x 1 rpw3 rpw3 23546 Jun 29 20:49 hello*
    $ ldd hello		# libs it depends on
     libecl.so => /usr/local/lib/ecl/libecl.so (0x0000002a9566d000)
     libdl.so.2 => /lib64/libdl.so.2 (0x0000002a9591e000)
     libm.so.6 => /lib64/tls/libm.so.6 (0x0000002a95a22000)
     libgmp.so.3 => /usr/lib64/libgmp.so.3 (0x0000002a95baa000)
     libc.so.6 => /lib64/tls/libc.so.6 (0x0000002a95ce2000)
     /lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000002a95556000)
    $ ls -l /usr/local/lib/ecl/libecl.so
    -rwxr-xr-x 1 root root 3421899 Jun 29 20:35 /usr/local/lib/ecl/libecl.so*
    $

O.k. so far: a 24 KB ELF executable and a 3.5 MB runtime library, plus
the other usual libc suspects. Looks very lightweight, yes? But here's
the issue [and, yes, this is the lowest of several runs, so "libecl.so"
will have been cached in memory by the operating system]:

    $ time ./hello
    Hello world!

    real    0m0.773s
    user    0m0.760s
    sys     0m0.010s
    $

Whereas a CMUCL "script", with a 260 KB ELF executable and a 23 MB core
file runs *much* faster!!  [And, yes, this is the lowest of several runs,
so the operating system has cached the core image, since it's mmap()'d.]

    $ cat ./hello2
    #!/usr/local/bin/cmucl -script
    (princ "Hello world!")
    (terpri)
    (quit)
    $ time ./hello2
    Hello world!

    real    0m0.016s
    user    0m0.010s
    sys     0m0.000s
    $ 

I can only imagine that the additional 3/4 second ECL is consuming is
coming from recreating the base core image from scratch every time,
*NOT* something you want to be doing in CGI scripts (say)...


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607