summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2019-05-21 18:58:23 +0800
committerJohn Hodge <tpg@ucc.asn.au>2019-05-21 18:58:23 +0800
commit84a9e0b722ac2b56a958720330592bc9e5ed7633 (patch)
treed5ff8de91483237813490bd101983df6566b65ce /src
parentb48167dec0c1c05b463991a8db5a8db70a5ae604 (diff)
downloadmrust-84a9e0b722ac2b56a958720330592bc9e5ed7633.tar.gz
rc_string - Use memcmp/strcmp (faster)
Diffstat (limited to 'src')
-rw-r--r--src/include/rc_string.hpp16
-rw-r--r--src/rc_string.cpp71
2 files changed, 31 insertions, 56 deletions
diff --git a/src/include/rc_string.hpp b/src/include/rc_string.hpp
index 94b6d9e7..2177e614 100644
--- a/src/include/rc_string.hpp
+++ b/src/include/rc_string.hpp
@@ -85,7 +85,12 @@ public:
return *(c_str() + size() - 1);
}
- Ordering ord(const RcString& s) const;
+ Ordering ord(const char* s, size_t l) const;
+ Ordering ord(const RcString& s) const {
+ if( m_ptr == s.m_ptr )
+ return OrdEqual;
+ return ord(s.c_str(), s.size());
+ }
bool operator==(const RcString& s) const {
if(s.size() != this->size())
return false;
@@ -99,13 +104,16 @@ public:
bool operator<(const RcString& s) const { return this->ord(s) == OrdLess; }
bool operator>(const RcString& s) const { return this->ord(s) == OrdGreater; }
- Ordering ord(const std::string& s) const;
+ Ordering ord(const std::string& s) const { return ord(s.data(), s.size()); }
bool operator==(const std::string& s) const { return this->ord(s) == OrdEqual; }
bool operator!=(const std::string& s) const { return this->ord(s) != OrdEqual; }
bool operator<(const std::string& s) const { return this->ord(s) == OrdLess; }
bool operator>(const std::string& s) const { return this->ord(s) == OrdGreater; }
- bool operator==(const char* s) const;
- bool operator!=(const char* s) const { return !(*this == s); }
+
+ Ordering ord(const char* s) const;
+ bool operator==(const char* s) const { return this->ord(s) == OrdEqual; }
+ bool operator!=(const char* s) const { return this->ord(s) != OrdEqual; }
+
friend ::std::ostream& operator<<(::std::ostream& os, const RcString& x);
friend bool operator==(const char* a, const RcString& b) {
diff --git a/src/rc_string.cpp b/src/rc_string.cpp
index 0d7e253a..123b4254 100644
--- a/src/rc_string.cpp
+++ b/src/rc_string.cpp
@@ -37,70 +37,35 @@ RcString::~RcString()
}
}
}
-Ordering RcString::ord(const RcString& x) const
+Ordering RcString::ord(const char* s, size_t len) const
{
- if( m_ptr == x.m_ptr )
- return OrdEqual;
- // Both can't be empty/null
if( m_ptr == nullptr )
- return OrdLess;
- if( x.m_ptr == nullptr )
+ return (len == 0 ? OrdEqual : OrdLess);
+ if( len == 0 )
return OrdGreater;
- assert(x.size() > 0);
assert(this->size() > 0);
+ assert(len > 0);
- auto xp = x.c_str();
- auto tp = this->c_str();
- for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++)
- {
- if( *xp != *tp )
- return ::ord((unsigned)*xp, (unsigned)*tp);
- xp ++;
- tp ++;
- }
- return ::ord((unsigned)this->size(), (unsigned)x.size());
+ int cmp = memcmp(this->c_str(), s, ::std::min(len, this->size()));
+ if(cmp == 0)
+ return ::ord(this->size(), len);
+ return ::ord(cmp, 0);
}
-Ordering RcString::ord(const std::string& x) const
+Ordering RcString::ord(const char* s) const
{
- if( m_ptr == nullptr && x.size() == 0 )
- return OrdEqual;
- // Both can't be empty/null
if( m_ptr == nullptr )
- return OrdLess;
- if( x.empty() )
- return OrdGreater;
-
- assert(x.size() > 0);
- assert(this->size() > 0);
+ return (*s == '\0' ? OrdEqual : OrdLess);
- auto xp = x.c_str();
- auto tp = this->c_str();
- for(size_t i = 0; i < ::std::min(this->size(), x.size()); i ++)
- {
- if( *xp != *tp )
- return ::ord((unsigned)*xp, (unsigned)*tp);
- xp ++;
- tp ++;
- }
- return ::ord((unsigned)this->size(), (unsigned)x.size());
-}
-bool RcString::operator==(const char* s) const
-{
- if( m_ptr == nullptr )
- return *s == '\0';
- const char* ts = this->c_str();
- const char* end = ts + this->size();
- // Loop while not at the end of either
- while(s && ts != end)
+ int cmp = strncmp(this->c_str(), s, this->size());
+ if( cmp == 0 )
{
- if( *s != *ts )
- return false;
- s ++;
- ts ++;
+ if( s[this->size()] == '\0' )
+ return OrdEqual;
+ else
+ return OrdLess;
}
- // Only equal if we're at the end of both strings
- return *s == '\0' && ts == end;
+ return ::ord(cmp, 0);
}
::std::ostream& operator<<(::std::ostream& os, const RcString& x)
@@ -125,12 +90,14 @@ RcString RcString::new_interned(const ::std::string& s)
}
return *it;
#else
+ // TODO: interning flag, so comparisons can just be a pointer comparison
return *RcString_interned_strings.insert(RcString(s)).first;
#endif
}
size_t std::hash<RcString>::operator()(const RcString& s) const noexcept
{
+ // http://www.cse.yorku.ca/~oz/hash.html "djb2"
size_t h = 5381;
for(auto c : s) {
h = h * 33 + (unsigned)c;