Commit b4fc73f7 authored by Issam I Safa's avatar Issam I Safa Committed by Facebook GitHub Bot

Use binary search over threads

Summary:
Switches a thread search from linear-time std::find to logarithmic-time std::binary_search.

Extracts the comparison into a separate function in ThreadList class.

Reviewed By: yfeldblum

Differential Revision: D28301992

fbshipit-source-id: 199728d82ca7d7fe8534f7163c76a6473b6f7c4b
parent 8140959e
...@@ -145,7 +145,7 @@ IOThreadPoolExecutor::pickThread() { ...@@ -145,7 +145,7 @@ IOThreadPoolExecutor::pickThread() {
// task is added by the clean up operations on thread destruction, thisThread_ // task is added by the clean up operations on thread destruction, thisThread_
// is not an available thread anymore, thus, always check whether or not // is not an available thread anymore, thus, always check whether or not
// thisThread_ is an available thread before choosing it. // thisThread_ is an available thread before choosing it.
if (me && std::find(ths.cbegin(), ths.cend(), me) != ths.cend()) { if (me && threadList_.contains(me)) {
return me; return me;
} }
auto n = ths.size(); auto n = ths.size();
......
...@@ -242,42 +242,30 @@ class ThreadPoolExecutor : public DefaultKeepAliveExecutor { ...@@ -242,42 +242,30 @@ class ThreadPoolExecutor : public DefaultKeepAliveExecutor {
class ThreadList { class ThreadList {
public: public:
void add(const ThreadPtr& state) { void add(const ThreadPtr& state) {
auto it = std::lower_bound( auto it = std::lower_bound(vec_.begin(), vec_.end(), state, Compare{});
vec_.begin(),
vec_.end(),
state,
// compare method is a static method of class
// and therefore cannot be inlined by compiler
// as a template predicate of the STL algorithm
// but wrapped up with the lambda function (lambda will be inlined)
// compiler can inline compare method as well
[&](const ThreadPtr& ts1, const ThreadPtr& ts2) -> bool { // inline
return compare(ts1, ts2);
});
vec_.insert(it, state); vec_.insert(it, state);
} }
void remove(const ThreadPtr& state) { void remove(const ThreadPtr& state) {
auto itPair = std::equal_range( auto itPair =
vec_.begin(), std::equal_range(vec_.begin(), vec_.end(), state, Compare{});
vec_.end(),
state,
// the same as above
[&](const ThreadPtr& ts1, const ThreadPtr& ts2) -> bool { // inline
return compare(ts1, ts2);
});
CHECK(itPair.first != vec_.end()); CHECK(itPair.first != vec_.end());
CHECK(std::next(itPair.first) == itPair.second); CHECK(std::next(itPair.first) == itPair.second);
vec_.erase(itPair.first); vec_.erase(itPair.first);
} }
bool contains(const ThreadPtr& ts) const {
return std::binary_search(vec_.cbegin(), vec_.cend(), ts, Compare{});
}
const std::vector<ThreadPtr>& get() const { return vec_; } const std::vector<ThreadPtr>& get() const { return vec_; }
private: private:
static bool compare(const ThreadPtr& ts1, const ThreadPtr& ts2) { struct Compare {
return ts1->id < ts2->id; bool operator()(const ThreadPtr& ts1, const ThreadPtr& ts2) const {
} return ts1->id < ts2->id;
}
};
std::vector<ThreadPtr> vec_; std::vector<ThreadPtr> vec_;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment