Dear list,
I have an inquiry about ancient technology.
I'm still using Gambit-C 3.0 on the following platforms: * MacOS 9.2.2 with Metrowerks Codewarrior 1 Pro * FreeDOS 12T24 with djgpp
I have compiled an R4RS scheme program on both platforms (*.scm -> *.o1). I noticed that the speedup is not that great, compared to interpreted code (~5x speedup). I don't use any declarations, I'm just loading the .o1 files. So my question: * how much would adding just "(declare (standard-bindings) (extended-bindings))" bring in terms of performance? * How do I declare the number type ? numbers are mostly floats, with some integer loop indices? * Does "(declare (block))" mean that I don't modify anything outside the scope of the module, or is it only meaningful for standalone executables?
Thanks a lot,
Alexander
Afficher les réponses par date
On 6/25/25 08:18, Alexander Shendi via Gambit-list wrote:
- how much would adding just "(declare (standard-bindings) (extended-bindings))" bring in terms of performance?
A fair amount, if you're not changing any built-in primitives (e.g., you're not extending + to work on things other than numbers), then I would do it.
- How do I declare the number type ? numbers are mostly floats, with some integer loop indices?
The HTML documentation says:
(number-type primitive...) Numeric arguments and result of the specified primitives are known to be of the given type (all primitives if none specified). number-type can be: `generic', `fixnum', or `flonum'.
There may be some rules about where such a form can appear, I would use this declaration as the first declaration in a file, or in a function body, or in a `(let ...)` form.
If you have a block of code that operates only on flonums, you could say
(let () (declare (flonum)) ... )
And the compiler will generate code such that all arithmetic operations will operate on flonums. This can be very granular, if you have only a single '+' that operates on fixnums, you can say
((let () (declare (fixnum) +) x y)
and that specific + will be compiled to code that operates only on fixnums.
The default safety declaration is
(declare (safe))
so if you declare arithmetic operations to be fixnum, it will generate code to check that the arguments are fixnums and the result is a fixnum; similarly for (declare (flonum)).
If you want arithmetic code to *not* check whether the arguments and results are appropriate, you can
(declare (not safe))
The HTML documentation says the default declarations are
(declare (ieee-scheme) (separate) (inline) (inlining-limit 300) (lambda-lift) (not standard-bindings) (not extended-bindings) (safe) (interrupts-enabled) (generic) )
- Does "(declare (block))" mean that I don't modify anything outside the scope of the module, or is it only meaningful for standalone executables?
You are declaring to the compiler that any functions or variables defined within the range of the (declare (block)) that are *not* redefined in the block will not be redefined in any other place in the program (e.g., in other files).
This allows certain optimizations, e.g., if you have
(let () (declare (block))
(define (foo x y) (+ x y)) ... (foo 1 2) ... )
Then the compiled code will skip the check that 'foo' was called with the correct number (2) of arguments.
Similar rules apply to the current compiler.
Brad