>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