I want to make sure I understand how 'load' works in Gambit. I have basic build system using a slightly modified version Snow up and running, and I'm making a few assertions that I want to make sure are true.
In Gambit, a 'load' and 'include' are obviously quite different because it's using machine-compiled code for compiled objects, not bytecode. I have heard (I have not tested this yet, although I will soon) that it's quite expensive to call code across module boundaries, which makes reasonable sense because it cannot simply use the 'goto'-style jump. So, for any high-performance application, you want to inline code when compiling if you don't need a shared library.
Now, I have my system separated into a few shared libraries (.o1 files), but there are cases when I want to inline code that is common between them. For example, I have a utilities package which is called quite often in all of the modules, and it makes sense to include this file rather than load it (for performance). However, doing so would include this file in all modules, so when the modules are loaded together, the same symbols are redefined.
If code is of the form
(load "lib") (include "util.scm")
(call-utility-function 'with 'some 'params)
and util.scm is also included in the "lib" library, is it same to assume that when the above code is compiled in Gambit that call-utility-function with resolve to the local version with a 'goto'-style jump? I don't see how it wouldn't since it has no idea about lib's version of call-utility-function until run-time, unless it does some sort of check at runtime? I know you can't redefine symbols in Gambit at compile-time, so I'm assuming it does a sort of static binding.
I'll be the first to admit that this may be a major case of pre-optimization. so slap me if I shouldn't be worrying about this as much.
Afficher les réponses par date
Ok, I just ran some tests to see the difference of calling code from a 'load' and an 'include'. I'm a bit confused. The tests with the loadable module were actually faster then the test that included the code. Can someone explain this?
--- util.scm (package* util/v1.0.0 (provide: (define* (getattr name alist _)))
(maintainer: "James Long <james at coptix.com>") (author: "James Long <james at coptix.com>") (homepage: "http://smallnum.blogspot.com") (description: "Utility") (keywords: flow))
(define* (getattr alist name (default #f)) (let ((r (assq name alist))) (if r (cdr r) default)))
--- moduletest.scm (package* moduletest/v1.0.0 (require: util/v1.0.0))
(define lst '((name . "James")))
(define (start n i) (if (< n i) (let* ((name (getattr lst 'name)) (chr (string-ref name 0))) (start (+ n 1) i))))
(start 0 10000000)
When the 'util' package is compiled inline (it uses "include"):
% time ./moduletest ./moduletest 2.38s user 0.04s system 90% cpu 2.655 total % time ./moduletest ./moduletest 2.36s user 0.02s system 98% cpu 2.418 total
And when the 'util' package is loaded in with 'load':
% time ./moduletest ./moduletest 2.00s user 0.03s system 90% cpu 2.252 total % time ./moduletest ./moduletest 1.99s user 0.02s system 99% cpu 2.029 total
I'm sure that I misunderstand the difference of 'load' and 'include', and I would be happy if someone could shed some light for me. I found a couple useful posts in the archive but not much. (I'm on OS X, macbook pro, with gambit v4.0)
On 9/2/07, James Long longster@gmail.com wrote: ...