From 3cfb99b28134e1acf8bad3fb672ff152dfd58601 Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Tue, 25 May 2004 17:59:31 +0000 Subject: [PATCH] added the possibility to get some statistical information from ex::compare() --- ginac/basic.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ ginac/basic.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- ginac/ex.h | 27 +++++++++++++++++++++++++-- 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/ginac/basic.cpp b/ginac/basic.cpp index 038cd7b5..3fcac861 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -808,10 +808,16 @@ ex basic::expand(unsigned options) const * 1 greater. */ int basic::compare(const basic & other) const { +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.total_basic_compares++; +#endif const unsigned hash_this = gethash(); const unsigned hash_other = other.gethash(); if (hash_thishash_other) return 1; +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.compare_same_hashvalue++; +#endif const unsigned typeid_this = tinfo(); const unsigned typeid_other = other.tinfo(); @@ -827,6 +833,9 @@ int basic::compare(const basic & other) const // std::cout << std::endl; // } // return cmpval; +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.compare_same_type++; +#endif return compare_same_type(other); } else { // std::cout << "hash collision, different types: " @@ -847,13 +856,22 @@ int basic::compare(const basic & other) const * @see is_equal_same_type */ bool basic::is_equal(const basic & other) const { +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.total_basic_is_equals++; +#endif if (this->gethash()!=other.gethash()) return false; +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.is_equal_same_hashvalue++; +#endif if (this->tinfo()!=other.tinfo()) return false; GINAC_ASSERT(typeid(*this)==typeid(other)); +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.is_equal_same_type++; +#endif return is_equal_same_type(other); } @@ -882,4 +900,27 @@ void basic::ensure_if_modifiable() const int max_recursion_level = 1024; + +#ifdef GINAC_COMPARE_STATISTICS +compare_statistics_t::~compare_statistics_t() +{ + std::clog << "ex::compare() called " << total_compares << " times" << std::endl; + std::clog << "nontrivial compares: " << nontrivial_compares << " times" << std::endl; + std::clog << "basic::compare() called " << total_basic_compares << " times" << std::endl; + std::clog << "same hashvalue in compare(): " << compare_same_hashvalue << " times" << std::endl; + std::clog << "compare_same_type() called " << compare_same_type << " times" << std::endl; + std::clog << std::endl; + std::clog << "ex::is_equal() called " << total_is_equals << " times" << std::endl; + std::clog << "nontrivial is_equals: " << nontrivial_is_equals << " times" << std::endl; + std::clog << "basic::is_equal() called " << total_basic_is_equals << " times" << std::endl; + std::clog << "same hashvalue in is_equal(): " << is_equal_same_hashvalue << " times" << std::endl; + std::clog << "is_equal_same_type() called " << is_equal_same_type << " times" << std::endl; + std::clog << std::endl; + std::clog << "basic::gethash() called " << total_gethash << " times" << std::endl; + std::clog << "used cached hashvalue " << gethash_cached << " times" << std::endl; +} + +compare_statistics_t compare_statistics; +#endif + } // namespace GiNaC diff --git a/ginac/basic.h b/ginac/basic.h index da634e08..a5b71a59 100644 --- a/ginac/basic.h +++ b/ginac/basic.h @@ -49,6 +49,38 @@ typedef std::vector exvector; typedef std::map exmap; +// Define this to enable some statistical output for comparisons and hashing +#undef GINAC_COMPARE_STATISTICS + +#ifdef GINAC_COMPARE_STATISTICS +class compare_statistics_t { +public: + compare_statistics_t() + : total_compares(0), nontrivial_compares(0), total_basic_compares(0), compare_same_hashvalue(0), compare_same_type(0), + total_is_equals(0), nontrivial_is_equals(0), total_basic_is_equals(0), is_equal_same_hashvalue(0), is_equal_same_type(0), + total_gethash(0), gethash_cached(0) {} + ~compare_statistics_t(); + + unsigned long total_compares; + unsigned long nontrivial_compares; + unsigned long total_basic_compares; + unsigned long compare_same_hashvalue; + unsigned long compare_same_type; + + unsigned long total_is_equals; + unsigned long nontrivial_is_equals; + unsigned long total_basic_is_equals; + unsigned long is_equal_same_hashvalue; + unsigned long is_equal_same_type; + + unsigned long total_gethash; + unsigned long gethash_cached; +}; + +extern compare_statistics_t compare_statistics; +#endif + + /** Function object for map(). */ struct map_function { typedef const ex & argument_type; @@ -212,7 +244,22 @@ public: int compare(const basic & other) const; bool is_equal(const basic & other) const; const basic & hold() const; - unsigned gethash() const { if (flags & status_flags::hash_calculated) return hashvalue; else return calchash(); } + + unsigned gethash() const + { +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.total_gethash++; +#endif + if (flags & status_flags::hash_calculated) { +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.gethash_cached++; +#endif + return hashvalue; + } else { + return calchash(); + } + } + unsigned tinfo() const {return tinfo_key;} /** Set some status_flags. */ diff --git a/ginac/ex.h b/ginac/ex.h index 95115a30..14695fd9 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -358,24 +358,47 @@ ex::ex(const std::string &s, const ex &l) : bp(construct_from_string_and_lst(s, inline int ex::compare(const ex & other) const { +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.total_compares++; +#endif if (bp == other.bp) // trivial case: both expressions point to same basic return 0; +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.nontrivial_compares++; +#endif const int cmpval = bp->compare(*other.bp); +#if 1 if (cmpval == 0) { // Expressions point to different, but equal, trees: conserve // memory and make subsequent compare() operations faster by - // making both expression point to the same tree. + // making both expressions point to the same tree. share(other); } +#endif return cmpval; } inline bool ex::is_equal(const ex & other) const { +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.total_is_equals++; +#endif if (bp == other.bp) // trivial case: both expressions point to same basic return true; - return bp->is_equal(*other.bp); +#ifdef GINAC_COMPARE_STATISTICS + compare_statistics.nontrivial_is_equals++; +#endif + const bool equal = bp->is_equal(*other.bp); +#if 0 + if (equal) { + // Expressions point to different, but equal, trees: conserve + // memory and make subsequent compare() operations faster by + // making both expressions point to the same tree. + share(other); + } +#endif + return equal; } -- 2.44.0