From 554a212834c54291cb35f8303548e722cf7dd047 Mon Sep 17 00:00:00 2001 From: Aayush Sabharwal Date: Tue, 19 Mar 2024 15:50:18 +0530 Subject: [PATCH] refactor: improve `symbolic_evaluate` performance --- src/trait.jl | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/trait.jl b/src/trait.jl index f2e3a29..4c05f2c 100644 --- a/src/trait.jl +++ b/src/trait.jl @@ -73,13 +73,11 @@ The returned value should either be a value or an expression involving symbolic not present as keys in `syms`. This is already implemented for -`symbolic_evaluate(expr::Union{Symbol, Expr}, syms::Dict{Symbol})`. +`symbolic_evaluate(expr::Union{Symbol, Expr}, syms::Dict)`. """ -function symbolic_evaluate(expr::Union{Symbol, Expr}, syms::Dict{Symbol}) - while (new_expr = MacroTools.postwalk(expr) do sym - return get(syms, sym, sym) - end) != expr - expr = new_expr +function symbolic_evaluate(expr::Union{Symbol, Expr}, syms::Dict) + while (newexpr = _symbolic_evaluate_helper(expr, syms)) != expr + expr = newexpr end return try eval(expr) @@ -88,6 +86,20 @@ function symbolic_evaluate(expr::Union{Symbol, Expr}, syms::Dict{Symbol}) end end +function _symbolic_evaluate_helper(expr, syms::Dict) + if (res = get(syms, expr, nothing)) !== nothing + return res + end + expr isa Expr || return expr + + newexpr = Expr(expr.head) + sizehint!(newexpr.args, length(expr.args)) + for arg in expr.args + push!(newexpr.args, _symbolic_evaluate_helper(arg, syms)) + end + newexpr +end + ############ IsTimeseriesTrait abstract type IsTimeseriesTrait end