Performance can suffer rather alarmingly when you try to do outlandish,
computation-intensive things in an interpreted language. This may seem an obvious truism.
interpreted one line at a time, by the runtime interpreter, when it executes. It is nowhere
near as fast as Perl or Java, which are also interpreted but which are
bytecode-driven languages. In Java or Perl, your text-edited code gets pre-cached and
compiled into an intermediate representation before it goes to the runtime
environment. The intermediate representation is called bytecode. It is
machine-dependent code that executes midway in speed between raw BASIC and fully compiled C.
The reason it runs fast is that expressions are already fully parsed, all constants are
precalculated, any lexical ambiguities have been fully resolved, and in general a lot of
works. Your plain-text code has to be parsed at runtime, and all (or most) of the above
occurs "just in time." That is to say, the CPU sits and waits. There is no pre-compile. No
intermediate representation of partially optimized and bound code. Just "here's the
function, now let's see if it parses and can be made to work." The interpreter may "see" all
of your code at load time, but it gets made into something executable on a line-by-line
So for example, if you have built a lot of complex objects with many layers of in-between
"child" objects, you've created some wicked possibilities for program slowdowns. For
reading!) Well, all you're trying to do in this humongous line of code is find 'button1' and
set its fill color to red. Simple enough. But look at what you're asking the interpreter to
do. First, the interpreter has to get access to the top object (theDoc) and traverse its
property list to see if there's an attached SVG object called 'svgTopPanel'. This calls for
an array indirection of the 'hash' kind, because any time you do:
your "dot operator" child objects internally. Once the child object has been found, its
properties can be accessed, the same way. So (in the above example) we next look at our
svgTopPanel via the class's getElementById() method to see if it has an
attached element (in its elements array) called 'button1'. If that succeeds, we call on the
getStyle() method to retrieve its style object. Finally, we then use the style's
setProperty() method to change the fill color.
Folks, that's a lot of indexing and node traversal just to set a darn fill color!
Now imagine that you have to do this operation many times per second because some
damn fool programmer has requested that an animation occur as part of an event handler. (Bad
idea! Event handlers should have fast-acting code.) Do you see the problem? We're
piling array indirection upon node-tree traversal upon CPU pipeline stall.
Fortunately, there is a workaround. But in our laziness as programmers (and let's face
it, the very BEST programmers are best precisely because they are LAZY!) we forget that a
tiny bit of attention to small details can boost program performance significantly.
In the above case, what you want to do is have a function execute as part of the page's
onload handler, in which hard-to-get-at objects (like that gosh-darn button's style
object) and associated methods are cached in global variables. And I don't mean nicely
orchestrated arrays, etc. If you're after brute performance (speed-speed-speed!), you
hard-code all the global names and cache everything in sight. (Don't introduce
new arrays if you're trying to get performance back!) Bottom line: When you need to set that
button's fill color, you should be able to do:
Which exeutes many times faster than that gosh-awful big expression of a few paragraphs
ago (see above).
Persistency of objects
One thing you do have to be wary of when using the cache-everything approach is that you
really do need to sock the cachables away into persistent storage. If you stash your
cache in the wrong kind of storage context or Call object, scope may be lost when you're
looking the other way and the JS garbage collection mechanism may unceremoniously trash
your cache. So do use your head.
Now, so; but. Imagine that your program has lots of accesses to properties
like this one, maybe inside loops, etc. The multipliers are such that you can bring your
whole program (or form, or SVG web page, or whatnot) to a standstill if you're sloppy about
these "little optimizations" (which aren't so little, in truth).
OK, so you want to stamp your document. Maybe you need to give reviewers some advice about the document's status or sensitivity. This tip from author Ted Padova demonstrates how to add stamps with the Stamp Tool along with related comments.