Copy link to clipboard
Copied
I have a long list of parts. Each part has 2 different number formats—one numeric, one alphanumeric. Format A (12-234567) is the same part as Format B (ABCD-EFGH-IJKL). I have 2 arrays in a 1:1 correlation with each other, meaning arrayNumeric[1000] and arrayAlphaMumeric[1000] are the same part.
The script works as intended but both arrays have a length of about 70k. My issue is there is a 2-5 second lag as the script searches through the arrays. I have the "same" script written in php and apache computes it instantly, so I'm confused as to what the performance issue is.
I see there is no IndexOf unless you add it as a prototype, and the code i see to add indexOf is the same as what I wrote. I cannot seem to find a faster way to search through the large arrays. Here's the function I made to search them.
function getXref(num) {
for ( i = 0 ; i < arrayNumeric.length; i++) {
if ( arrayNumeric == num ) {
return arrayAlphaMumeric;
}
}
}
There seems to be a performance issue regardless of debug level, whether extendscript toolkit is closed or open, or if i write to console or not. So my question is basically what's the best way to handle finding values in large arrays?
Copy link to clipboard
Copied
Hi SpicyDodge,
By nature, a linear loop in an unsorted 70K array may become a heavy task if the underlying data structure is not optimized. There are many ways of improving the process, this depends on your data and goal.
• Is arrayNumeric an actual array of numbers? (It looks like format A refers to strings of the form "##-######"?)
• In case you use numbers, can arrayNumeric be sorted? If sorted, a binary search would dramatically speed up the process.
• Also, what is the range of format A numbers? If the range is known at the beginning, you may improve the internal encoding of your data. Sometimes U+FFFF (String rather than Array) is a great approach, as you can invoke indexOf and/or pattern matching through regex.
• Are both arrayNumeric and arrayAlphaNumeric hard-coded once and for all? If so, the Array structure is not necessary the best option. A 1:1 map could be designed as a { key=>val } Object instead, which then relies on JS hash mechanism, pretty good in ExtendScript.
Best,
Marc
Copy link to clipboard
Copied
Thank you for your informative reply. I can merge the two arrays into a key => val format. I was reluctant to take that approach initially as I'm coming from php and there appears to be no such thing as an associative array in JavaScript which is what I need.
Is there a better way to handle this than for (key in array)?
Copy link to clipboard
Copied
You can do (the equivalent of) associative arrays in JavaScript. E.g.
parts = {};
parts['12-234567'] = 'ABCD-EFGH-IJKL';
parts['12-234568'] = 'ABCD-EFGH-IJKM';
// etc.
But whether JavaScript handles such long assoc with any efficiency I don't know.
As Marc mentioned, binary searches are very fast on long arrays, but they do require that the arrays are sorted.
P.
Copy link to clipboard
Copied
spicyDoge a écrit
Thank you for your informative reply. I can merge the two arrays into a key => val format. I was reluctant to take that approach initially as I'm coming from php and there appears to be no such thing as an associative array in JavaScript which is what I need.
Is there a better way to handle this than for (key in array)?
Once you have declared a 1:1 map as follows,
const parts =
{
'12-234567' : 'ABCD-EFGH-IJKL',
'12-234568' : 'ABCD-EFGH-IJKM',
'12-234569' : 'ABCD-EFGH-IJKN',
// etc
};
you no longer need to loop in (this would have no advantage over a regular Array!).
Simply use parts[key] to get the match; parts.hasOwnProperty(key) tells whether that key exists.
(However, I still suspect that keys like '12-234567' could have, internally, a better encoding.)
Best,
Marc
Copy link to clipboard
Copied
I went ahead and created an object, list = {"alpha":"numeral",....); I used the function below to get the value from prop, where the property is the A format and the value is the B format. So getting
var list = {object}
function getAlphaNumeric(num)
{
if ( list.hasOwnProperty(num))
{
return list[num];
}
}
that improved the script performance tremendously. issue is going in the opposite way to pull the property from the value. using a for loop and comparing list.valueOf(property) to myValue and returning property takes a pretty long time as well.
So the most optimal approach seems to have 2 objects, one "format A:format B" and another "format B:format A" then using the function above to get the xref number.
If theres yet a faster way please enlighten me, if this is pretty much as good as it gets i thank you for your help.
Copy link to clipboard
Copied
Just to expand on Marc's example:
'12-234567' in parts ; // returns true or false
parts['12-234567'] ; // returns value eg. 'ABCD-EFGH-IJKL' or undefined
parts['12-234567'] === undefined ; // returns true or false
Question is: What's the fasted way with an object that contains thousands of key-value pairs?
Regards,
Uwe