/usr/share/jed/doc/txt/program.txt is in jed-common 1:0.99.19-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | This document provides some tips for writing better and more efficient
S-Lang code. It is not meant to be a tutorial on S-Lang.
Writing Fast Routines
=====================
The first thing that one must realize is that S-Lang is an interpreted
language and runs much slower than a compiled language. This fact can be
used to justify a rule of thumb that may be used to gauge the speed of a
S-Lang expression:
Rule of Thumb: All single token intrinsic statements and expressions run
at the same speed.
The phrase ``intrinsic statements and expressions'' includes not only
intrinsic functions but also assignment operations as well as pushing an
object on the stack. For example, consider the expression:
n = down (20);
This expression consists of the operation of pushing `20' onto the stack
followed by calling the intrinsic function `down' and assigning it to
`n'. It is easiest to see this using the RPN form:
. 20 down =n
(Remember, all RPN expressions must lie on lines that begin with a
period.). From the above rule of thumb, this expression executes at a
speed of 3 units.
Now consider something more tricky. Consider the expression:
n = n + 1;
It also executes in 3 units of time. This is equivalent to:
n++;
However, `n++' is a single token and executes in 1 unit of time! So, the
rule is that one should try to use the `++' and `--' forms whenever
possible. The same statement is true for the `+=' and `-=' operators.
The statement:
n += 1;
parses to two tokens:
. 1 +=n;
and executes in 2 units. Note that
n++; n++;
also achieves the effect `n = n + 2' but executes in 2 units as well.
At this point, it should be clear that the code that executes the fastest
is the code that contains the least number of tokens. However, this is
only partially true and only holds for expressions that do not call other
S-Lang functions.
As an example, consider the recursive function below:
define fib (); % definition required for recursion
define fib(n)
{
if (n == 0) return(0);
if (n == 1) return(1);
return fib(n - 1) + fib(n - 2);
}
The first thing to do is to change
if (n == 0) return 0;
to
!if (n) return 0;
since the expression `n == 0' executes in 3 units and `n' executes in
only 1. Similarly, the statement:
if (n == 1) return 1;
may be written:
n--; !if (n) return 1;
with the side effect that n is reduced by 1 in the process. But that is
a good thing because we can then modify:
return fib (n - 1) + fib (n - 2);
to:
return fib(n) + fib (n - 1);
Actually, we can do better than that. We can write `n - 1' which
executes in 3 units to the equivalent expression `n--, n' that executes
in 2 units to produce:
return fib (n) + fib (n--, n);
Here the fact that `n--' does not affect the stack makes this possible.
Finally, we are left with:
define fib (n)
{
!if (n) return 0;
n--; !if (n) return 1;
return fib(n) + fib (n--, n);
}
Simply counting tokens (if, !if, fib, n, ==, 1, -, etc...) shows that the
unoptimized version has 19 whereas the optimized version has 12. Applying
the rule of thumb to this suggests that the optimized version should run
19/12 times faster! The reader is encouraged to compare the speed of the
first version of `fib' with the optimized version to verify that this is
indeed the case (use something like fib(25)).
Here is a brief summary of what to do to squeeze extra speed out of
S-Lang:
1. Use the `++', `--', `+=', and `-=' forms wherever possible.
2. Eliminate `if (something == 0)' in favor of `!if (something)'
3. Avoid `while(1)' and use `forever' instead.
4. For simple looping a fixed number of times use `loop'.
5. If you have something like:
for (i = imin; i <= imax; i += di)
{
...
}
replace it by the MUCH faster and smaller version
_for (imin, imax, di)
{
i = ();
.
.
}
6. For multiplication by 2 use the `mul2' function.
7. To square a number, do not use `x * x'. Use `sqr(x)'.
Writing Memory Efficient Routines
=================================
In the previous section, it was emphasized that routines that use the
least number of tokens are the fastest. Since they use the smallest
number of tokens, they take up less space and and are more memory
efficient.
|