Skip to main content
Inspiring
November 23, 2015
Question

Slow request processing after upgrade to Java 1.7 on CF9 / calling UDF

  • November 23, 2015
  • 2 replies
  • 545 views

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:

    This topic has been closed for replies.

    2 replies

    Carl Von Stetten
    Legend
    November 27, 2015

    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.

    brookdAuthor
    Inspiring
    December 1, 2015

    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..

    Carl Von Stetten
    Legend
    December 2, 2015

    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.

    WolfShade
    Legend
    November 23, 2015

    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,

    ^_^