Home Forums General XMetaL Discussion Does using associative arrays slow things down? Reply To: Does using associative arrays slow things down?

Derek Read

Reply to: Does using associative arrays slow things down?

I don't think arrays are your issue (arrays in JScript are fast and would not be the bottleneck most of the time).

I think the most likely bottleneck would be usage of ActiveDocument.getNodesByXpath as it can be a fairly expensive call to make on large and complex documents ( = many nodes and / or complex node structure).

You may also wish to look at your usage of FormattingUpdating. Turning that off and then on will cause the document to be reformatted and if you are not modifying the document (as in your example) then calling it should not be necessary and would trigger an unnecessary complete reformat of the document. However, if you are making changes to the document this API will stop the document from flickering all over the place, and also in this case it will actually be faster as the document reformatting will only take place once at the very end of your script. I don't think your script is doing anything that would require this API (though perhaps this is not your real script).

It is possible to obtain identical results using the Range method instead of getNodesByXPath by visiting each element in the document in turn (or by jumping to elements with a specific name). Range is generally quite fast when used this way. Also, putting some of this inside a function might make things slightly faster (that part is relying directly on the JScript engine).

[code]//XMetaL Script Language JScript:

//Define a new function for searching within arrays
Array.prototype.exists = function(strVal){
for (var i=0; i if (this == strVal) {
return true;
return false;

Visit every element in the document and put all Pointer
and Target values into two different arrays.

Note: Might be slightly faster (depending on document
size and complexity) if rewritten to visit specific
elements rather than visiting all elements.

var rng = ActiveDocument.Range;
var pointerAttrs = new Array();
var targetAttrs = new Array();
var i1 = 0;
var i2 = 0;
var msg = “”;

while (rng.MoveToElement()) {
pointerAttr = rng.ContainerAttribute(“Pointer”);
if (pointerAttr > “”) {
pointerAttrs[i1] = pointerAttr;
Note: Not sure if is it really necessary to
do the following check. Putting empty values into
the array might be slightly faster. However, we
check these later on (when searching) so that tradeoff
might go either way. If speed is of real importance
test though two scenarios.
targetAttr = rng.ContainerAttribute(“Target”);
if (targetAttr > “”) {
targetAttrs[i2] = targetAttr;

//Now that we have two arrays containing all values
//call the prototype function to see if Target values exist for each Pointer
for(var k=0;k if(!targetAttrs.exists(pointerAttrs[k])) {
msg += “Target not found in this document: ” + k + ” – ” + pointerAttrs[k] + “n”;
if (msg > “”) {