lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] odd/any_member-opt a6e80e5 3/5: Use a sorted vector


From: Greg Chicares
Subject: [lmi-commits] [lmi] odd/any_member-opt a6e80e5 3/5: Use a sorted vector instead of std::map<> in MemberSymbolTable [292]
Date: Sun, 28 Mar 2021 13:53:15 -0400 (EDT)

branch: odd/any_member-opt
commit a6e80e5ef93ffefa4e4f21c0c66c2e960312a369
Author: Vadim Zeitlin <vadim@tt-solutions.com>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Use a sorted vector instead of std::map<> in MemberSymbolTable [292]
    
    This is slightly faster than using a map and, more importantly, provides
    scope for the upcoming optimizations.
---
 any_member.hpp | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/any_member.hpp b/any_member.hpp
index 94c0951..cdca2c9 100644
--- a/any_member.hpp
+++ b/any_member.hpp
@@ -543,9 +543,6 @@ MemberType const* member_cast(any_member<ClassType> const& 
member)
 template<typename ClassType>
 class MemberSymbolTable
 {
-    typedef std::map<std::string, any_member<ClassType>> member_map_type;
-    typedef typename member_map_type::value_type member_pair_type;
-
   public:
     virtual ~MemberSymbolTable();
 
@@ -569,7 +566,7 @@ class MemberSymbolTable
     [[noreturn]]
     void complain_that_no_such_member_is_ascribed(std::string const&) const;
 
-    member_map_type map_;
+    std::vector<any_member<ClassType>> member_values_;
     std::vector<std::string> member_names_;
 };
 
@@ -606,12 +603,12 @@ any_member<ClassType>& 
MemberSymbolTable<ClassType>::operator[]
     (std::string const& s
     )
 {
-    auto i = map_.find(s);
-    if(map_.end() == i)
+    auto const i = std::lower_bound(member_names_.begin(), 
member_names_.end(), s);
+    if(i == member_names_.end() || (*i != s))
         {
         complain_that_no_such_member_is_ascribed(s);
         }
-    return i->second;
+    return member_values_[i - member_names_.begin()];
 }
 
 template<typename ClassType>
@@ -619,12 +616,7 @@ any_member<ClassType> const& 
MemberSymbolTable<ClassType>::operator[]
     (std::string const& s
     ) const
 {
-    auto const i = map_.find(s);
-    if(map_.end() == i)
-        {
-        complain_that_no_such_member_is_ascribed(s);
-        }
-    return i->second;
+    return (const_cast<MemberSymbolTable<ClassType>&>(*this))[s];
 }
 
 template<typename ClassType>
@@ -649,10 +641,15 @@ void MemberSymbolTable<ClassType>::ascribe
             >::value
         );
 
+    auto const i = std::lower_bound(member_names_.begin(), 
member_names_.end(), s);
+
     ClassType* class_object = static_cast<ClassType*>(this);
-    map_.insert(member_pair_type(s, any_member<ClassType>(class_object, p2m)));
-    // TODO ?? This would appear to be O(N^2).
-    auto i = std::lower_bound(member_names_.begin(), member_names_.end(), s);
+
+    auto const index = i - member_names_.begin();
+    member_values_.emplace(member_values_.begin() + index, class_object, p2m);
+
+    // Notice that insert() may invalidate the iterator, so it can only be done
+    // after using "i" for computing the index into member_values_ above.
     member_names_.insert(i, s);
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]