deep inspection of arguments to Java methods is too expensive

Description

(originally reported as Railo-3282 - https://issues.jboss.org/browse/RAILO-3282)

Our code makes extensive use of Java objects - some of which are relatively complex and large. In one case, we discovered that when we passed one of these objects to a Java method, Railo was taking several seconds to do a deep inspection of an object with about 1000 nodes - [about 2ms per node] - Railo appears to be looking for ObjectWrap objects - see .../runtime/reflection/Reflector.java - cleanArgs() and various _clean() methods

The method in question may be called multiple times in the course of a request, leading to completely unacceptable performance (8-10 seconds for an average page view... where 200ms or less is expected)

In this particular instance, our object implements Map - and our preliminary work-around is to create a simple wrapper object of our own which cleanArgs() doesn't know how to inspect - this work-around appears to be OK in preliminary testing, but (at a minimum) some further information about ObjectWrap objects is needed (when does Railo need to wrap objects??) so we can be sure this doesn't bite us later

Also... it appears (from review of Reflector.java) that some of the _clean() methods may result in objects (effectively) being passed by value instead of by reference if an ObjectWrap member is found

==============

to reproduce the problem... compile the attached 'CallTimer.java' and make it available to your instance (change the package as needed). Then run this code (changing the CreateObject call as needed for your environment):

{{itemCount = 100000;
timer = CreateObject("java","com.paperthin.common.test.CallTimer");
foo = CreateObject("java","java.util.TreeMap").init();
for (i = 0; i LT itemCount; i = 1 + i)
foo["node#i#"] = i;

WriteOutput("overhead for #itemCount# items: #timer.getCallOverhead(getTickCount(),foo)#ms<br />");}}

Environment

Java 1.8.0_51-b16 - 64 bits - Windows 7 with all available patches
Dual core, 16GB memory, over 2GB free

Attachments

1

Activity

Pothys - MitrahSoft 
2 November 2021 at 08:03

As per reporter said I marked this ticket as resolved

Tim Parker 
1 November 2021 at 23:40

This appears to be resolved with 5.3.8.206. I have removed work-around logic without performance degradation, so it appears that this can be closed out now

Tim Parker 
20 May 2021 at 17:20
(edited)

This is still an issue with Lucee 5.3.7.47 and Java 11

We call a Java method and pass the Request object to it - if we don't clone Request to a local struct and clear it first, the call we make takes over 500ms - otherwise (with the clone, the call, and the clone back), the entire sequence takes less than 1ms

Tim Parker 
13 April 2020 at 20:04

I will have to test this again without our work-around. Given that we do have a work-around deployed, the priority for this is not critical, but it would be nice for us to be able to clean out at least one ‘if Lucee’ from our codebase

Pothys - MitrahSoft 
9 April 2020 at 13:57

, Any update on this issue? If Yes, please update here. And it'll improve the status of the ticket. Or otherwise, can I close the ticket?

Unresolved

Details

Assignee

Reporter

Priority

New Issue warning screen

Before you create a new Issue, please post to the mailing list first https://dev.lucee.org

Once the issue has been verified, one of the Lucee team will ask you to file an issue

Affects versions

Created 28 October 2015 at 15:56
Updated 2 November 2021 at 08:03