Performance of numeric operations

Kawa can generally do a pretty good job of generating
efficient code for numeric operations, at least when
it knows or can figure out the types of the operands.

The basic operations +, -, and *
are compiled to single-instruction bytecode if both
operands are int or long.
Likewise, if both operands are floating-point (or
one is floating-point and the other is rational),
then single-instruction double or float
instructions are emitted.

A binary operation involing an infinite-precision integer
and a fixed-size int or long is normally
evaluated by expanding the latter to integer
and using integer arithmetic. An exception is the
integer argument is an integer literal whose
value fits in a int or long - in that case
the operation is done using int or long
arithmetic.

In general, integer literals have amorphous type.
When used to infer the type of a variable, they have integer type:

(let ((v1 0))
... v1 has type integer ... )

However, a literal whose value fits in the int or long range
is implicitly viewed int or long in certain contexts,
primarily method overload resolution and binary arithmethic
(as mentioned above).

The comparison functions <, <=, =,
>, and => are also optimized to single instriction
operations if the operands have appropriate type.
However, the functions zero?, positive?, and negative?
have not yet been optimized.
Instead of (positive? x) write (> x 0).

There are a number of integer division and modulo operations.
If the operands are int or long, it is faster
to use quotient and remainder rather
than div and mod (or modulo).
If you know the first operand is non-negative and the second is positive,
then use quotient and remainder.
(If an operand is an arbitrary-precision integer,
then it dosn’t really matter.)

The logical operations bitwise-and, bitwise-ior,
bitwise-xor, bitwise-not, bitwise-arithmetic-shift-left,
bitwise-arithmetic-shift-right are compiled
to single bitcode instructions if the operands are int or long.
Avoid bitwise-arithmetic-shift if the sign of the shift is known.
If the operands are arbitrary-precision integer,
a library call is needed, but run-time type dispatch is avoided.