FLEE slows down when conurrent requests are made

May 20, 2008 at 6:09 PM
I have a high volume application. It executes about 200 concurrent reqs / sec. If I don't have any expressions to evaluate, execution time is about 10 ms per rer. If I have expressions to evaluate,  FLEE code is executed and response time shoots up to 200 ms and CPU utilization goes upto 90 percent. Any idea about how to solve this?

This is how I am using FLEE:

ExpressionContext

context = new ExpressionContext();

 

context.Imports.AddType(

typeof(Math));
context.Imports.AddType(
typeof(CustomOperations));

//Code to add bunch of expression variables and values
context.Variables[ExpressionDefinitions.PID] = objExpEvalData.PubID; ... and so on.

 

IGenericExpression

<bool> eGeneric = ExpressionFactory.CreateGeneric<bool>(strExpression, context);
bool blnResult = eGeneric.Evaluate();

 

May 21, 2008 at 8:51 PM
Edited May 21, 2008 at 9:05 PM
Nimittdesai,

I don't know if I can help you with your problem, but I just wanted to know if you were using any type of queuing or threading to concurrently execute your requests? 

I would expect the time it takes to evaluate an expression verses a request with no expression to be significantly higher.  FLEE uses regular expressions to parse the formula string then builds an expression tree of formulas and parameters. Then when you call the Evaluate method it takes that expression tree and determines the result.  This means that FLEE's performance is heavily based on the complexity of the formulas.

Returning to my question... if you send 200 expressions of moderately to highly complex formulas to evaluate at the same time with misconfigured of no performance management, you could see your CPU utilization shoot up and ultimately create bottlenecks for other processes.

This is all of course a suggestion as I am no expert on FLEE.

-Mindcore


May 23, 2008 at 8:10 PM

This is how I am planning to solve it.

For every expression evaluated, cache eGeneric object in httpruntime cache with expression as key. This way eGeneric object with compiled expression already exists.  We set the context on that object and execute eGeneric.evaluate(). I modified expression.vb so that context is read/write property. New code looks like this:

 

IGenericExpression

<bool> eGeneric = (IGenericExpression<bool>)objWebCache.Get(strExpression);

 

 

if (eGeneric == null)
{
eGeneric =
ExpressionFactory.CreateGeneric<bool>(strExpression, context);
objWebCache.Store(strExpression, eGeneric, cacheTTL]
);

lock
(eGeneric)
{
    blnResult = eGeneric.Evaluate();
}
}
else
{
lock (eGeneric)
    {
        eGeneric.Context = context;
        blnResult = eGeneric.Evaluate();
    }
}
return blnResult;

Do you see any problems with this approach?