Frederik Petersen created NIFI-6322:
---------------------------------------

             Summary: Evaluator Objects are rebuilt on every call even when a 
CompiledExpression is used
                 Key: NIFI-6322
                 URL: https://issues.apache.org/jira/browse/NIFI-6322
             Project: Apache NiFi
          Issue Type: Bug
          Components: Core Framework
    Affects Versions: 1.9.2
            Reporter: Frederik Petersen
         Attachments: Selection_094.png, image.png

Hi, 

While doing some CPU sampling in our production environment, we encountered 
some strange results. It seems like that, during the evaluation of NiFi 
expressions, the modification of a _HashSet_ is the most expensive operation in 
this process. 

!Selection_094.png!


This feels pretty unrealistic considering all the other processing related to 
evaluating NiFi expressions. 
After reviewing some code and some profiling it just looks like this _HashSet_ 
modification is performed way more often than required. Especially that it is 
done at each evaluation.

!image.png!
This profiling output was produced with the following unit test:


{code:java}
@Test
public void testSimple() {
 final TestRunner runner = TestRunners.newTestRunner(new RouteOnAttribute());
 runner.setProperty(RouteOnAttribute.ROUTE_STRATEGY, 
RouteOnAttribute.ROUTE_ANY_MATCHES.getValue());
 runner.setProperty("filter", "${literal('b'):equals(${a})}");
 for (int i = 0; i < 500; i++) {
 runner.enqueue(new byte[0], new HashMap<String, String>() {{
 put("a", "b");
 }});
 }
 runner.run(500);
}{code}

The key question is: Why are the _Evaluator_ Objects (and all the stuff related 
to it) built twice:
- Once in _ExpressionCompiler.compile()_
- Once again in _CompiledExpression.evaluate()_

In other words: Every call to _CompiledExpression.evaluate()_ leads to a new 
_ExpressionCompiler_ being created and expensive calls being made. Why not just 
reuse _Evaluator_ objects created beforehand that are sroted in the 
_CompiledExpression_?

Is there a specific design decision behind that? It looks like there is room 
for performance improvement, especially for heavily used processors.

On our live system, where we perform expensive tasks like language detection, 
mail parsing and such, this situation causes the most amount of CPU eaten by 
the expression language evaluation.

Thank you very much for looking into this.

 



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to