>From a443d9907737390cda05c1c14da7c6c1044f25db Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 27 Feb 2015 18:56:08 +0100 Subject: [PATCH] Allow computing MemberSymbolTable member access index and reusing it. Looking up the member by name once and then reusing the index to access it results in a big performance gain when doing it many times in a row, e.g. CensusView::column_value_varies_across_cells() now takes less than 30% of the time it took before for a census with ~4000 rows. --- any_member.hpp | 28 ++++++++++++++++++++++------ census_view.cpp | 7 +++++-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/any_member.hpp b/any_member.hpp index 8e5f4a6..ca34394 100644 --- a/any_member.hpp +++ b/any_member.hpp @@ -548,6 +548,9 @@ class MemberSymbolTable bool equals(MemberSymbolTable const&) const; std::vector const& member_names() const; + size_t get_member_index(std::string const&) const; + any_member const& get_member_by_index(size_t) const; + protected: MemberSymbolTable(); @@ -616,17 +619,30 @@ void MemberSymbolTable::complain_that_no_such_member_is_ascribed } template -any_member& MemberSymbolTable::operator[] - (std::string const& s - ) +size_t MemberSymbolTable::get_member_index(std::string const& s) const { - typedef std::vector::iterator svi; - svi i = std::lower_bound(member_names_.begin(), member_names_.end(), s); + typedef std::vector::const_iterator svci; + svci i = std::lower_bound(member_names_.begin(), member_names_.end(), s); if(member_names_.end() == i || s != *i) { complain_that_no_such_member_is_ascribed(s); } - return member_values_[i - member_names_.begin()]; + return i - member_names_.begin(); +} + +template +any_member const& +MemberSymbolTable::get_member_by_index(size_t n) const +{ + return member_values_[n]; +} + +template +any_member& MemberSymbolTable::operator[] + (std::string const& s + ) +{ + return member_values_[get_member_index(s)]; } template diff --git a/census_view.cpp b/census_view.cpp index cfc3f66..eb7be4b 100644 --- a/census_view.cpp +++ b/census_view.cpp @@ -936,9 +936,12 @@ Input* CensusView::class_parms_from_class_name(std::string const& class_name) const any_member& case_value = case_parms()[0][header]; typedef std::vector::const_iterator ici; - for(ici j = cells.begin(); j != cells.end(); ++j) + ici j = cells.begin(); + size_t const header_index = j->get_member_index(header); + + for(; j != cells.end(); ++j) { - if(!((*j)[header] == case_value)) + if(!(j->get_member_by_index(header_index) == case_value)) { return true; } -- 2.1.0