Skip to content

Commit 9d493a4

Browse files
committed
refactor: improve performance
1 parent 4c15daa commit 9d493a4

File tree

3 files changed

+63
-81
lines changed

3 files changed

+63
-81
lines changed

src/core/intrusive_string_list.h

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ class ISLEntry {
9292
e.data_ = nullptr;
9393
}
9494

95-
~ISLEntry() {
95+
// consider manual removing, we waste a lot of time to check nullptr
96+
inline ~ISLEntry() {
9697
Clear();
9798
}
9899

@@ -102,33 +103,33 @@ class ISLEntry {
102103
return *this;
103104
}
104105

105-
bool Empty() const {
106+
inline bool Empty() const {
106107
return !Raw();
107108
}
108109

109-
operator bool() const {
110+
inline operator bool() const {
110111
return !Empty();
111112
}
112113

113-
bool IsVector() const {
114+
inline bool IsVector() const {
114115
return (uptr() & kVectorBit) != 0;
115116
}
116117

117-
std::vector<ISLEntry>& AsVector() {
118+
inline std::vector<ISLEntry>& AsVector() {
118119
return *reinterpret_cast<std::vector<ISLEntry>*>(Raw());
119120
}
120121

121-
std::string_view Key() const {
122+
inline std::string_view Key() const {
122123
DCHECK(!IsVector());
123124
return {GetKeyData(), GetKeySize()};
124125
}
125126

126-
bool HasExpiry() const {
127+
inline bool HasExpiry() const {
127128
return (uptr() & kExpiryBit) != 0;
128129
}
129130

130131
// returns the expiry time of the current entry or UINT32_MAX if no expiry is set.
131-
uint32_t GetExpiry() const {
132+
inline uint32_t GetExpiry() const {
132133
std::uint32_t res = UINT32_MAX;
133134
if (HasExpiry()) {
134135
DCHECK(!IsVector());
@@ -142,7 +143,7 @@ class ISLEntry {
142143
return this;
143144
}
144145

145-
uint64_t GetExtendedHash() const {
146+
inline uint64_t GetExtendedHash() const {
146147
return (uptr() & kExtHashShiftedMask) >> kExtHashShift;
147148
}
148149

@@ -265,7 +266,7 @@ class ISLEntry {
265266
}
266267

267268
// TODO refactor, because it's inefficient
268-
uint32_t Insert(ISLEntry&& e) {
269+
inline uint32_t Insert(ISLEntry&& e) {
269270
if (Empty()) {
270271
*this = std::move(e);
271272
return 0;
@@ -298,7 +299,8 @@ class ISLEntry {
298299
return AsVector().size();
299300
}
300301

301-
ISLEntry& operator[](uint32_t pos) {
302+
// TODO remove, it is inefficient
303+
inline ISLEntry& operator[](uint32_t pos) {
302304
DCHECK(!Empty());
303305
if (!IsVector()) {
304306
DCHECK(pos == 0);
@@ -358,7 +360,11 @@ class ISLEntry {
358360
}
359361

360362
protected:
361-
void Clear() {
363+
inline void Clear() {
364+
// TODO add optimization to avoid destructor calls during vector allocator
365+
if (!data_)
366+
return;
367+
362368
if (IsVector()) {
363369
delete &AsVector();
364370
} else {
@@ -383,70 +389,45 @@ class ISLEntry {
383389
return size;
384390
}
385391

386-
uint64_t uptr() const {
392+
inline uint64_t uptr() const {
387393
return uint64_t(data_);
388394
}
389395

390-
char* Raw() const {
396+
inline char* Raw() const {
391397
return (char*)(uptr() & ~kTagMask);
392398
}
393399

394-
void SetExpiryBit(bool b) {
400+
inline void SetExpiryBit(bool b) {
395401
if (b)
396402
data_ = (char*)(uptr() | kExpiryBit);
397403
else
398404
data_ = (char*)(uptr() & (~kExpiryBit));
399405
}
400406

401-
void SetVectorBit() {
407+
inline void SetVectorBit() {
402408
data_ = (char*)(uptr() | kVectorBit);
403409
}
404410

405-
void SetSsoBit() {
411+
inline void SetSsoBit() {
406412
data_ = (char*)(uptr() | kSsoBit);
407413
}
408414

409-
bool HasSso() const {
415+
inline bool HasSso() const {
410416
return (uptr() & kSsoBit) != 0;
411417
}
412418

413-
size_t Size() {
419+
inline size_t Size() {
414420
size_t key_field_size = HasSso() ? 1 : 4;
415421
size_t expiry_field_size = HasExpiry() ? 4 : 0;
416422
return expiry_field_size + key_field_size + GetKeySize();
417423
}
418-
std::uint32_t GetExpirySize() const {
424+
425+
inline std::uint32_t GetExpirySize() const {
419426
return HasExpiry() ? sizeof(std::uint32_t) : 0;
420427
}
421428

422-
// TODO add optimization for big keys
423429
// memory daya layout [Expiry, key_size, key]
424430
char* data_ = nullptr;
425431
};
426432

427-
// template <class T, std::enable_if_t<std::is_invocable_v<T, std::string_view>>* = nullptr>
428-
// bool Scan(const T& cb, uint32_t* set_size, uint32_t curr_time) {
429-
// for (auto it = start_; it && it.ExpiryTime() <= curr_time; it = start_) {
430-
// start_ = it.Next();
431-
// ISLEntry::Destroy(it);
432-
// (*set_size)--;
433-
// }
434-
435-
// for (auto curr = start_, next = start_; curr; curr = next) {
436-
// cb(curr.Key());
437-
// next = curr.Next();
438-
// for (auto tmp = next; tmp && tmp.ExpiryTime() <= curr_time; tmp = next) {
439-
// (*set_size)--;
440-
// next = next.Next();
441-
// ISLEntry::Destroy(tmp);
442-
// }
443-
// curr.SetNext(next);
444-
// }
445-
// return start_;
446-
// }
447-
448-
// size_t ObjMallocUsed() const {
449-
// return obj_malloc_used_;
450-
// };
451-
452433
} // namespace dfly

src/core/intrusive_string_set.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,16 +321,17 @@ class IntrusiveStringSet {
321321
auto prev_size = 1 << prev_capacity_log;
322322
for (int64_t bucket_id = prev_size - 1; bucket_id >= 0; --bucket_id) {
323323
auto bucket = std::move(entries_[bucket_id]);
324+
// TODO add optimization for package processing
324325
for (uint32_t pos = 0, size = bucket.ElementsNum(); pos < size; ++pos) {
326+
// TODO operator [] is inefficient and it is better to avoid it
325327
if (bucket[pos]) {
326328
auto new_bucket_id =
327329
bucket[pos].Rehash(bucket_id, prev_capacity_log, capacity_log_, kShiftLog);
328-
// TODO remove
329-
// auto real_bucket_id = BucketId(Hash(bucket[i].Key()), capacity_log_);
330-
// DCHECK(real_bucket_id == bucket_id);
331330

331+
// TODO add optimization for package processing
332332
new_bucket_id = FindEmptyAround(new_bucket_id);
333333

334+
// insert method is inefficient
334335
entries_[new_bucket_id]->Insert(std::move(bucket[pos]));
335336
}
336337
}

src/core/intrusive_string_set_test.cc

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,12 @@ TEST_F(IntrusiveStringSetTest, Fill) {
607607
}
608608
}
609609

610-
// TEST_F(IntrusiveStringSetTest, IterateEmpty) {
611-
// for (const auto& s : *ss_) {
612-
// // We're iterating to make sure there is no crash. However, if we got here, it's a bug
613-
// CHECK(false) << "Found entry " << s << " in empty set";
614-
// }
615-
// }
610+
TEST_F(IntrusiveStringSetTest, IterateEmpty) {
611+
for (const auto& s : *ss_) {
612+
// We're iterating to make sure there is no crash. However, if we got here, it's a bug
613+
CHECK(false) << "Found entry " << s << " in empty set";
614+
}
615+
}
616616

617617
// size_t memUsed(IntrusiveStringSet& obj) {
618618
// return obj.ObjMallocUsed() + obj.SetMallocUsed();
@@ -778,33 +778,33 @@ TEST_F(IntrusiveStringSetTest, Fill) {
778778
// ->ArgNames({"elements", "Key Size"})
779779
// ->ArgsProduct({{1000, 10000, 100000}, {10, 100, 1000}});
780780

781-
// void BM_Grow(benchmark::State& state) {
782-
// vector<string> strs;
783-
// mt19937 generator(0);
784-
// IntrusiveStringSet src;
785-
// unsigned elems = 1 << 18;
786-
// for (size_t i = 0; i < elems; ++i) {
787-
// src.Add(random_string(generator, 16), UINT32_MAX);
788-
// strs.push_back(random_string(generator, 16));
789-
// }
790-
791-
// while (state.KeepRunning()) {
792-
// state.PauseTiming();
793-
// IntrusiveStringSet tmp;
794-
// src.Fill(&tmp);
795-
// CHECK_EQ(tmp.Capacity(), elems);
796-
// state.ResumeTiming();
797-
// for (const auto& str : strs) {
798-
// tmp.Add(str);
799-
// if (tmp.Capacity() > elems) {
800-
// break; // we grew
801-
// }
802-
// }
781+
void BM_Grow(benchmark::State& state) {
782+
vector<string> strs;
783+
mt19937 generator(0);
784+
IntrusiveStringSet src;
785+
unsigned elems = 1 << 18;
786+
for (size_t i = 0; i < elems; ++i) {
787+
src.Add(random_string(generator, 16), UINT32_MAX);
788+
strs.push_back(random_string(generator, 16));
789+
}
790+
791+
while (state.KeepRunning()) {
792+
state.PauseTiming();
793+
IntrusiveStringSet tmp;
794+
src.Fill(&tmp);
795+
CHECK_EQ(tmp.Capacity(), elems);
796+
state.ResumeTiming();
797+
for (const auto& str : strs) {
798+
tmp.Add(str);
799+
if (tmp.Capacity() > elems) {
800+
break; // we grew
801+
}
802+
}
803803

804-
// CHECK_GT(tmp.Capacity(), elems);
805-
// }
806-
// }
807-
// BENCHMARK(BM_Grow);
804+
CHECK_GT(tmp.Capacity(), elems);
805+
}
806+
}
807+
BENCHMARK(BM_Grow);
808808

809809
// unsigned total_wasted_memory = 0;
810810

0 commit comments

Comments
 (0)