Skip to content

Commit 6ef8212

Browse files
committed
microoptimizations
- improve bool and str hash() speed - optimize str.find(char)
1 parent 5926766 commit 6ef8212

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

src/runtime/bool.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ extern "C" Box* boolRepr(BoxedBool* v) {
3939
return false_str;
4040
}
4141

42-
extern "C" Box* boolHash(BoxedBool* v) {
43-
return boxInt(v == True);
42+
size_t bool_hash(BoxedBool* v) {
43+
return v == True;
44+
}
45+
46+
Box* boolHash(BoxedBool* v) {
47+
return boxInt(bool_hash(v));
4448
}
4549

4650
extern "C" Box* boolNew(Box* cls, Box* val) {
@@ -96,6 +100,7 @@ void setupBool() {
96100
bool_cls->giveAttr("__xor__", new BoxedFunction(boxRTFunction((void*)boolXor, BOXED_BOOL, 2)));
97101

98102
bool_cls->freeze();
103+
bool_cls->tp_hash = (hashfunc)bool_hash;
99104
}
100105

101106
void teardownBool() {

src/runtime/str.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,11 @@ extern "C" size_t strHashUnboxed(BoxedString* self) {
15841584
}
15851585

15861586
extern "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

15901594
extern "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

Comments
 (0)