Highlighted

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

New Here ,
Nov 23, 2015

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:

23-11-2015 10-49-52 AM.png

Views

285

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

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

New Here ,
Nov 23, 2015

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:

23-11-2015 10-49-52 AM.png

Views

286

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Nov 23, 2015 0
LEGEND ,
Nov 23, 2015

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,

^_^

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 23, 2015 0
Most Valuable Participant ,
Nov 27, 2015

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.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 27, 2015 0
New Here ,
Nov 30, 2015

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

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 30, 2015 0
Most Valuable Participant ,
Dec 01, 2015

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.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 01, 2015 0