public static NodeSizes Calculate(Expression node)
            {
                var calculator = new NodeSizeCalculator();

                calculator.Visit(node);
                return(new NodeSizes(totalSize: calculator.size, nodes: calculator.nodes.Values));
            }
Beispiel #2
0
        // 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);
        }
Beispiel #3
0
            public static NodeSizes Calculate(Expression node)
            {
                var calculator = new NodeSizeCalculator();

                calculator.Visit(node);
                return(new NodeSizes {
                    TotalSize = calculator.size, Nodes = calculator.nodes.Values
                });
            }