Fix performance issue

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-07-29 20:59:15 -07:00
parent 08b750c825
commit 4efa9a92df
5 changed files with 48 additions and 18 deletions

View file

@ -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;
} }

View file

@ -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);
// ======================================= // =======================================
} }

View file

@ -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;

View file

@ -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)

View 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;
}