MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / optimize

Method optimize

src/expr/src/linear.rs:977–1031  ·  view source on GitHub ↗

Optimize the internal expression evaluation order. This method performs several optimizations that are meant to streamline the execution of the `MapFilterProject` instance, but not to alter its semantics. This includes extracting expressions that are used multiple times, inlining those that are not, and removing expressions that are unreferenced. This method will inline all temporal expressions,

(&mut self)

Source from the content-addressed store, hash-verified

975 /// );
976 /// ```
977 pub fn optimize(&mut self) {
978 // Track sizes and iterate as long as they decrease.
979 let mut prev_size = None;
980 let mut self_size = usize::max_value();
981 // Continue as long as strict improvements occur.
982 while prev_size.map(|p| self_size < p).unwrap_or(true) {
983 // Lock in current size.
984 prev_size = Some(self_size);
985
986 // We have an annoying pattern of mapping literals that already exist as columns (by filters).
987 // Try to identify this pattern, of a map that introduces an expression equated to a prior column,
988 // and then replace the mapped expression by a column reference.
989 //
990 // We think this is due to `LiteralLifting`, and we might investigate removing the introduciton in
991 // the first place. The tell-tale that we see when we fix is a diff that look likes
992 //
993 // - Project (#0, #2)
994 // - Filter (#1 = 1)
995 // - Map (1)
996 // - Get l0
997 // + Filter (#1 = 1)
998 // + Get l0
999 //
1000 for (index, expr) in self.expressions.iter_mut().enumerate() {
1001 // If `expr` matches a filter equating it to a column < index + input_arity, rewrite it
1002 for (_, predicate) in self.predicates.iter() {
1003 if let Some(col) =
1004 E::equality_column_alias(predicate, expr, index + self.input_arity)
1005 {
1006 *expr = col;
1007 }
1008 }
1009 }
1010
1011 // Optimization memoizes individual `ScalarExpr` expressions that
1012 // are sure to be evaluated, canonicalizes references to the first
1013 // occurrence of each, inlines expressions that have a reference
1014 // count of one, and then removes any expressions that are not
1015 // referenced.
1016 self.memoize_expressions();
1017 self.predicates.sort();
1018 self.predicates.dedup();
1019 self.inline_expressions();
1020 self.remove_undemanded();
1021
1022 // Re-build `self` from parts to restore evaluation order invariants.
1023 let (map, filter, project) = self.as_map_filter_project();
1024 *self = Self::new(self.input_arity)
1025 .map(map)
1026 .filter(filter)
1027 .project(project);
1028
1029 self_size = self.size();
1030 }
1031 }
1032
1033 /// Total expression sizes across all expressions.
1034 pub fn size(&self) -> usize {

Callers 5

extract_temporalMethod · 0.45
extract_commonMethod · 0.45
create_fromMethod · 0.45
test_mfpFunction · 0.45
normalizeMethod · 0.45

Calls 11

enumerateMethod · 0.80
memoize_expressionsMethod · 0.80
sortMethod · 0.80
inline_expressionsMethod · 0.80
remove_undemandedMethod · 0.80
as_map_filter_projectMethod · 0.80
mapMethod · 0.45
iterMethod · 0.45
projectMethod · 0.45
filterMethod · 0.45
sizeMethod · 0.45

Tested by 1

test_mfpFunction · 0.36