Fix performance issue
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
08b750c825
commit
4efa9a92df
5 changed files with 48 additions and 18 deletions
|
@ -14,10 +14,12 @@ class deep_copy_fn {
|
||||||
expr_cell_map<expr> m_cache;
|
expr_cell_map<expr> m_cache;
|
||||||
|
|
||||||
expr apply(expr const & a) {
|
expr apply(expr const & a) {
|
||||||
|
bool sh = false;
|
||||||
if (is_shared(a)) {
|
if (is_shared(a)) {
|
||||||
auto r = m_cache.find(a.raw());
|
auto r = m_cache.find(a.raw());
|
||||||
if (r != m_cache.end())
|
if (r != m_cache.end())
|
||||||
return r->second;
|
return r->second;
|
||||||
|
sh = true;
|
||||||
}
|
}
|
||||||
expr r;
|
expr r;
|
||||||
switch (a.kind()) {
|
switch (a.kind()) {
|
||||||
|
@ -33,7 +35,7 @@ class deep_copy_fn {
|
||||||
case expr_kind::Lambda: r = lambda(abst_name(a), apply(abst_type(a)), apply(abst_body(a))); break;
|
case expr_kind::Lambda: r = lambda(abst_name(a), apply(abst_type(a)), apply(abst_body(a))); break;
|
||||||
case expr_kind::Pi: r = pi(abst_name(a), apply(abst_type(a)), apply(abst_body(a))); break;
|
case expr_kind::Pi: r = pi(abst_name(a), apply(abst_type(a)), apply(abst_body(a))); break;
|
||||||
}
|
}
|
||||||
if (is_shared(a))
|
if (sh)
|
||||||
m_cache.insert(std::make_pair(a.raw(), r));
|
m_cache.insert(std::make_pair(a.raw(), r));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,21 +77,10 @@ public:
|
||||||
|
|
||||||
friend void swap(expr & a, expr & b) { std::swap(a.m_ptr, b.m_ptr); }
|
friend void swap(expr & a, expr & b) { std::swap(a.m_ptr, b.m_ptr); }
|
||||||
|
|
||||||
expr & operator=(expr const & s) {
|
void release() { if (m_ptr) m_ptr->dec_ref(); m_ptr = nullptr; }
|
||||||
if (s.m_ptr)
|
|
||||||
s.m_ptr->inc_ref();
|
expr & operator=(expr const & s) { LEAN_COPY_REF(expr, s); }
|
||||||
if (m_ptr)
|
expr & operator=(expr && s) { LEAN_MOVE_REF(expr, s); }
|
||||||
m_ptr->dec_ref();
|
|
||||||
m_ptr = s.m_ptr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
expr & operator=(expr && s) {
|
|
||||||
if (m_ptr)
|
|
||||||
m_ptr->dec_ref();
|
|
||||||
m_ptr = s.m_ptr;
|
|
||||||
s.m_ptr = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
expr_kind kind() const { return m_ptr->kind(); }
|
expr_kind kind() const { return m_ptr->kind(); }
|
||||||
unsigned hash() const { return m_ptr->hash(); }
|
unsigned hash() const { return m_ptr->hash(); }
|
||||||
|
@ -345,5 +334,4 @@ struct args {
|
||||||
*/
|
*/
|
||||||
expr copy(expr const & e);
|
expr copy(expr const & e);
|
||||||
// =======================================
|
// =======================================
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,13 @@ class replace_fn {
|
||||||
F m_f;
|
F m_f;
|
||||||
|
|
||||||
expr apply(expr const & e, unsigned offset) {
|
expr apply(expr const & e, unsigned offset) {
|
||||||
|
bool sh = false;
|
||||||
if (is_shared(e)) {
|
if (is_shared(e)) {
|
||||||
expr_cell_offset p(e.raw(), offset);
|
expr_cell_offset p(e.raw(), offset);
|
||||||
auto it = m_cache.find(p);
|
auto it = m_cache.find(p);
|
||||||
if (it != m_cache.end())
|
if (it != m_cache.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
|
sh = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr r = m_f(e, offset);
|
expr r = m_f(e, offset);
|
||||||
|
@ -68,7 +70,7 @@ class replace_fn {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_shared(e))
|
if (sh)
|
||||||
m_cache.insert(std::make_pair(expr_cell_offset(e.raw(), offset), r));
|
m_cache.insert(std::make_pair(expr_cell_offset(e.raw(), offset), r));
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -13,3 +13,6 @@ add_test(free_vars ${CMAKE_CURRENT_BINARY_DIR}/free_vars)
|
||||||
add_executable(level level.cpp)
|
add_executable(level level.cpp)
|
||||||
target_link_libraries(level ${EXTRA_LIBS})
|
target_link_libraries(level ${EXTRA_LIBS})
|
||||||
add_test(level ${CMAKE_CURRENT_BINARY_DIR}/level)
|
add_test(level ${CMAKE_CURRENT_BINARY_DIR}/level)
|
||||||
|
add_executable(replace replace.cpp)
|
||||||
|
target_link_libraries(replace ${EXTRA_LIBS})
|
||||||
|
add_test(replace ${CMAKE_CURRENT_BINARY_DIR}/replace)
|
||||||
|
|
35
src/tests/kernel/replace.cpp
Normal file
35
src/tests/kernel/replace.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
||||||
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
|
|
||||||
|
Author: Leonardo de Moura
|
||||||
|
*/
|
||||||
|
#include "expr.h"
|
||||||
|
#include "abstract.h"
|
||||||
|
#include "deep_copy.h"
|
||||||
|
#include "name.h"
|
||||||
|
#include "test.h"
|
||||||
|
using namespace lean;
|
||||||
|
|
||||||
|
expr mk_big(expr f, unsigned depth, unsigned val) {
|
||||||
|
if (depth == 1)
|
||||||
|
return constant(name(val));
|
||||||
|
else
|
||||||
|
return f(mk_big(f, depth - 1, val << 1), mk_big(f, depth - 1, (val << 1) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tst1() {
|
||||||
|
expr f = constant("f");
|
||||||
|
expr r = mk_big(f, 16, 0);
|
||||||
|
expr n = constant(name(0u));
|
||||||
|
for (unsigned i = 0; i < 20; i++) {
|
||||||
|
r = abstract(n, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
continue_on_violation(true);
|
||||||
|
tst1();
|
||||||
|
std::cout << "done" << "\n";
|
||||||
|
return has_violations() ? 1 : 0;
|
||||||
|
}
|
Loading…
Reference in a new issue