public static NodeSizes Calculate(Expression node) { var calculator = new NodeSizeCalculator(); calculator.Visit(node); return(new NodeSizes(totalSize: calculator.size, nodes: calculator.nodes.Values)); }
// Reduces the size of a supplied expression tree by compiling parts of the tree into individual // delegates. Besides preventing the CLR from throwing stack overflow exceptions (which will happen // when the tree gets somewhere between 20,000 and 50,000 nodes), this can reduce the amount of code // that needs to be JITted and can therefore reduce the memory footprint of the application. private static Expression ReduceObjectGraphSize(Expression expression, Container container, Dictionary <Expression, InvocationExpression> reducedNodes = null) { var results = NodeSizeCalculator.Calculate(expression); while (results.TotalSize > container.Options.MaximumNumberOfNodesPerDelegate) { reducedNodes = reducedNodes ?? new Dictionary <Expression, InvocationExpression>(16); Expression mostReductiveNode = FindMostReductiveNodeOrNull(results, container.Options.MaximumNumberOfNodesPerDelegate); if (mostReductiveNode == null) { // In case mostReductiveNode is null, there's no good candidate to reduce the object // graph. In that case we break out. break; } // If the found mostReductiveNode has been reduced before, we use the previously compiled // value (instead of doing the compilation all over again). Otherwise we compile that node. InvocationExpression replacementNode = reducedNodes.ContainsKey(mostReductiveNode) ? reducedNodes[mostReductiveNode] : CompileToInvocation(mostReductiveNode, container, reducedNodes); reducedNodes[mostReductiveNode] = replacementNode; expression = NodeReplacer.Replace(expression, oldNode: mostReductiveNode, newNode: replacementNode); results = NodeSizeCalculator.Calculate(expression); } return(expression); }
public static NodeSizes Calculate(Expression node) { var calculator = new NodeSizeCalculator(); calculator.Visit(node); return(new NodeSizes { TotalSize = calculator.size, Nodes = calculator.nodes.Values }); }