Skip to content

Commit 79e2dd1

Browse files
committed
[*] Optimize variables lookup. Add cache.
1 parent 6d3f435 commit 79e2dd1

2 files changed

Lines changed: 41 additions & 24 deletions

File tree

Expressions/src/Expression.cpp

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ namespace mexpr
66
inline namespace
77
{
88
Expression diff_sum_sub_impl(
9-
const std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
9+
std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
1010
const std::string_view var) {
1111

12-
const auto& [type, lhs, rhs] = bexpr;
12+
auto& [type, lhs, rhs] = bexpr;
1313
bool lhs_contains_var = lhs->contains_var(var);
1414
bool rhs_contains_var = rhs->contains_var(var);
1515

@@ -23,10 +23,10 @@ Expression diff_sum_sub_impl(
2323
}
2424

2525
Expression diff_mul_impl(
26-
const std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
26+
std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
2727
const std::string_view var) {
2828

29-
const auto& [type, lhs, rhs] = bexpr;
29+
auto& [type, lhs, rhs] = bexpr;
3030
bool lhs_contains_var = lhs->contains_var(var);
3131
bool rhs_contains_var = rhs->contains_var(var);
3232
if (not(lhs_contains_var or rhs_contains_var)) {
@@ -53,10 +53,10 @@ Expression diff_mul_impl(
5353
}
5454

5555
Expression diff_div_impl(
56-
const std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
56+
std::tuple<binary_expr_type, std::unique_ptr<Expression>, std::unique_ptr<Expression>>& bexpr,
5757
const std::string_view var) {
5858

59-
const auto& [type, lhs, rhs] = bexpr;
59+
auto& [type, lhs, rhs] = bexpr;
6060
bool lhs_contains_var = lhs->contains_var(var);
6161
bool rhs_contains_var = rhs->contains_var(var);
6262

@@ -105,31 +105,35 @@ Expression diff_div_impl(
105105
}
106106
} // namespace
107107

108-
Expression::Expression(int val) : value_{val} {
108+
Expression::Expression(int val) : variable_lookup_cache_{}, value_{val} {
109109
}
110110

111111

112-
Expression::Expression(std::string name) : value_{name} {
112+
Expression::Expression(std::string name) : variable_lookup_cache_{{name, true}}, value_{name} {
113113
}
114114

115115

116116
Expression::Expression(unary_expr_type expr_type, std::unique_ptr<Expression> expr)
117-
: value_{std::make_tuple(expr_type, std::move(expr))} {
117+
: variable_lookup_cache_{}
118+
, value_{std::make_tuple(expr_type, std::move(expr))} {
118119
}
119120

120121

121122
Expression::Expression(unary_expr_type expr_type, Expression&& expr)
122-
: value_{std::make_tuple(expr_type, std::make_unique<Expression>(std::move(expr)))} {
123+
: variable_lookup_cache_{}
124+
, value_{std::make_tuple(expr_type, std::make_unique<Expression>(std::move(expr)))} {
123125
}
124126

125127

126128
Expression::Expression(binary_expr_type expr_type, std::unique_ptr<Expression> lhs, std::unique_ptr<Expression> rhs)
127-
: value_{std::make_tuple(expr_type, std::move(lhs), std::move(rhs))} {
129+
: variable_lookup_cache_{}
130+
, value_{std::make_tuple(expr_type, std::move(lhs), std::move(rhs))} {
128131
}
129132

130133

131134
Expression::Expression(binary_expr_type expr_type, Expression&& lhs, Expression&& rhs)
132-
: value_{std::make_tuple(
135+
: variable_lookup_cache_{}
136+
, value_{std::make_tuple(
133137
expr_type,
134138
std::make_unique<Expression>(std::move(lhs)),
135139
std::make_unique<Expression>(std::move(rhs)))} {
@@ -151,11 +155,11 @@ Expression Expression::clone() const {
151155
}
152156

153157

154-
Expression Expression::diff(const std::string_view var) const {
158+
Expression Expression::diff(const std::string_view var) {
155159

156160
if (std::holds_alternative<binary_expr>(value_)) {
157161
// first unpack variant value
158-
const auto& bexpr = std::get<binary_expr>(value_);
162+
auto& bexpr = std::get<binary_expr>(value_);
159163
// then unpack tuple from variant value
160164
const auto& type = std::get<0>(bexpr);
161165
switch (type) {
@@ -165,8 +169,8 @@ Expression Expression::diff(const std::string_view var) const {
165169
case binary_expr_type::div: return diff_div_impl(bexpr, var);
166170
}
167171
} else if (std::holds_alternative<unary_expr>(value_)) {
168-
const auto& uexpr = std::get<unary_expr>(value_);
169-
const auto& [type, value] = uexpr;
172+
auto& uexpr = std::get<unary_expr>(value_);
173+
auto& [type, value] = uexpr;
170174
switch (type) {
171175
case unary_expr_type::unary_minus:
172176
return value->contains_var(var) //
@@ -251,18 +255,29 @@ std::string Expression::to_string() const {
251255
}
252256

253257

254-
bool Expression::contains_var(const std::string_view var) const {
258+
bool Expression::contains_var(const std::string_view var) {
259+
const auto cache_hit = variable_lookup_cache_.find(var);
260+
if (cache_hit != variable_lookup_cache_.end()) {
261+
return cache_hit->second;
262+
}
263+
255264
if (std::holds_alternative<binary_expr>(value_)) {
256265
const auto& bexpr = std::get<binary_expr>(value_);
257-
return std::get<1>(bexpr)->contains_var(var) or std::get<2>(bexpr)->contains_var(var);
266+
bool result = std::get<1>(bexpr)->contains_var(var) or std::get<2>(bexpr)->contains_var(var);
267+
variable_lookup_cache_.emplace(var, result);
268+
return result;
258269
} else if (std::holds_alternative<unary_expr>(value_)) {
259270
const auto& uexpr = std::get<unary_expr>(value_);
260-
return std::get<1>(uexpr)->contains_var(var);
271+
bool result = std::get<1>(uexpr)->contains_var(var);
272+
variable_lookup_cache_.emplace(var, result);
273+
return result;
261274
} else if (std::holds_alternative<std::string>(value_)) {
262-
return std::get<std::string>(value_) == var;
263-
} else {
264-
return false;
275+
bool result = std::get<std::string>(value_) == var;
276+
variable_lookup_cache_.emplace(var, result);
265277
}
278+
279+
variable_lookup_cache_.emplace(var, false);
280+
return false;
266281
}
267282

268283

Expressions/src/Expression.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <string_view>
88
#include <tuple>
99
#include <variant>
10+
#include <unordered_map>
1011

1112
namespace mexpr
1213
{
@@ -44,14 +45,15 @@ class Expression
4445

4546
public:
4647
[[nodiscard]] Expression clone() const;
47-
[[nodiscard]] Expression diff(std::string_view var) const;
48+
[[nodiscard]] Expression diff(std::string_view var);
4849

4950
std::string to_expr_string() const;
5051
std::string to_string() const;
5152

52-
bool contains_var(std::string_view var) const;
53+
bool contains_var(std::string_view var);
5354

5455
private:
56+
std::unordered_map<std::string_view, bool> variable_lookup_cache_;
5557
std::variant<int, std::string, unary_expr, binary_expr> value_;
5658
};
5759
} // namespace mexpr

0 commit comments

Comments
 (0)