Copy link to clipboard
Copied
We're running CF9 and recently upgrade to Java 1.7 from 1.6, all of a sudden we're seeing something very strange. We're returning query results and for each row we're converting it to a struct (to return an array of structs) using a UDF method (the UDF library is loaded in the application scope), queryRowToStruct(). Each call to this method is taking 1000 ms. Previously it was taking 15-30 ms.
The weird thing is, that restarting the CF service brings it back down to 15-30 ms (which we discovered after rolling back to Java 1.6 which also reduced time down to 15+ ms, and then back to 1.7 and it was still at 15-30 ms). The UDF is pretty simple (it is included below), but the array and string functions appear to be running super slow. What could cause this??
The UDF code:
function queryRowToStruct(query,row,cols,padyesno){
//a var for looping
var ii = 1;
//the struct to return
var stReturn = structnew();
if (arraylen(arguments) lt 3 or not isdefined('cols')){
cols = listToArray(query.columnList.toLowerCase());
}
if (arraylen(arguments) lt 4 or not isdefined('padyesno')){
padyesno=false;
}
if (row EQ ''){row = 1;}
//if there is a second argument, use that for the row number
if(arrayLen(arguments) GT 1)
row = arguments[2];
//loop over the cols and build the struct from the query row
for(ii = 1; ii lte arraylen(cols); ii = ii + 1){
if (padyesno){
if (not isNumeric(query[cols[ii]][row]) and (query[cols[ii]][row] is 'yes' or query[cols[ii]][row] is 'no')){
stReturn[lcase(cols[ii])] = query[cols[ii]][row] & application.gs.jsonEscapeChar;
}else{
stReturn[lcase(cols[ii])] = query[cols[ii]][row];
};
}else{
stReturn[lcase(cols[ii])] = query[cols[ii]][row];
};
}
//return the struct
return stReturn;
}
The requests are timing out and its always at this chunk of code that is taking forever:
Copy link to clipboard
Copied
Java 1.7 u 31 introduced tighter network security and does not play well with CF9 or CF10. If you are up for it, upgrade to CF11, and make sure you've got the one with Java 1.8 - it works just fine.
HTH,
^_^
Copy link to clipboard
Copied
There might be a couple of micro-optimizations that could help, but it seems to be slow when processing the "lcase" BIF. Maybe there is something different in the underlying Java string library between Java 1.6 and 1.7.
You might replace your IsDefined() calls near the top of the function with StructKeyExists() to look for the required keys in the Arguments scope. You might also add a local variable to store the length of the "cols" array so you only have to do ArrayLen(cols) once - then substitute the local variable in your for loop (otherwise, ArrayLen() is called on each iteration of the loop).
As I said, these are micro-optimizations, but depending on how many rows are being processed in your queries, they can add up.
HTH,
-Carl V.
Copy link to clipboard
Copied
Thanks Carl, I did in fact do some of thes optimizations after opening this thread, and it did improve performance but not enough. Had to roll back to 1.6..... Gonna do the CF 11 upgrade soon, the scary part is the serialize/deserializeJSON methods that always seem to change between version and always have bugs. I have to run all my returned data through a series of regular expressions to make the JSON valid after serializing it and add/remove placeholder chars. Upgrades are not always fun with that mess..
Copy link to clipboard
Copied
I've never relied fully on ColdFusion's SerializeJSON due to all the bugs/inconsistencies. I prefer to use Ben Nadel's JSONSerializer.cfc or Nathan Mische's JSONUtil.cfc. They are compatible with older versions of ColdFusion.
-Carl V.