@@ -1584,7 +1584,11 @@ extern "C" size_t strHashUnboxed(BoxedString* self) {
15841584}
15851585
15861586extern " C" Box* strHash (BoxedString* self) {
1587- return boxLong (strHashUnboxed (self));
1587+ return boxInt (str_hash (self));
1588+ }
1589+
1590+ size_t str_hash (BoxedString* self) noexcept {
1591+ return strHashUnboxed (self);
15881592}
15891593
15901594extern " C" Box* strNonzero (BoxedString* self) {
@@ -1827,8 +1831,14 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
18271831 int max_replaces = static_cast <BoxedInt*>(_maxreplace)->n ;
18281832 size_t start_pos = 0 ;
18291833 std::string s = self->s ();
1834+
1835+ bool single_char = old->size () == 1 ;
18301836 for (int num_replaced = 0 ; num_replaced < max_replaces || max_replaces < 0 ; ++num_replaced) {
1831- start_pos = s.find (old->s (), start_pos);
1837+ if (single_char)
1838+ start_pos = s.find (old->s ()[0 ], start_pos);
1839+ else
1840+ start_pos = s.find (old->s (), start_pos);
1841+
18321842 if (start_pos == std::string::npos)
18331843 break ;
18341844 s.replace (start_pos, old->size (), new_->s ());
@@ -1841,7 +1851,11 @@ Box* strPartition(BoxedString* self, BoxedString* sep) {
18411851 RELEASE_ASSERT (PyString_Check (self), " " );
18421852 RELEASE_ASSERT (PyString_Check (sep), " " );
18431853
1844- size_t found_idx = self->s ().find (sep->s ());
1854+ size_t found_idx;
1855+ if (sep->size () == 1 )
1856+ found_idx = self->s ().find (sep->s ()[0 ]);
1857+ else
1858+ found_idx = self->s ().find (sep->s ());
18451859 if (found_idx == std::string::npos)
18461860 return BoxedTuple::create ({ self, EmptyString, EmptyString });
18471861
@@ -2063,7 +2077,12 @@ Box* strContains(BoxedString* self, Box* elt) {
20632077
20642078 BoxedString* sub = static_cast <BoxedString*>(elt);
20652079
2066- size_t found_idx = self->s ().find (sub->s ());
2080+ size_t found_idx;
2081+ if (sub->size () == 1 )
2082+ // Call the much-faster single-character find():
2083+ found_idx = self->s ().find (sub->s ()[0 ]);
2084+ else
2085+ found_idx = self->s ().find (sub->s ());
20672086 if (found_idx == std::string::npos)
20682087 return False;
20692088 return True;
@@ -2841,6 +2860,7 @@ void setupStr() {
28412860 str_cls->tp_as_sequence ->sq_slice = str_slice;
28422861 str_cls->tp_as_sequence ->sq_length = str_length;
28432862 str_cls->tp_iter = (decltype (str_cls->tp_iter ))strIter;
2863+ str_cls->tp_hash = (hashfunc)str_hash;
28442864
28452865 basestring_cls->giveAttr (" __doc__" ,
28462866 boxString (" Type basestring cannot be instantiated; it is the base for str and unicode." ));
0 commit comments