perf: minor perf wins (#4216)

* perf: faster tr_buffer::toString()

* perf: faster tr_buffer::Iterator

* perf: get mutex lock in reconnectPulse() instead of closeBadPeers()
This commit is contained in:
Charles Kerr 2022-11-21 09:28:46 -06:00 committed by GitHub
parent ffd5e6bf50
commit 76bea25f6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 37 deletions

View File

@ -2422,8 +2422,6 @@ struct ComparePeerByActivity
void closeBadPeers(tr_swarm* s, time_t const now_sec)
{
auto const lock = s->unique_lock();
for (auto* peer : getPeersToClose(s, now_sec))
{
closePeer(peer);
@ -2433,9 +2431,8 @@ void closeBadPeers(tr_swarm* s, time_t const now_sec)
void enforceTorrentPeerLimit(tr_swarm* swarm)
{
// do we have too many peers?
auto const n = swarm->peerCount();
auto const max = swarm->tor->peerLimit();
if (n <= max)
if (auto const n = swarm->peerCount(); n <= max)
{
return;
}
@ -2480,6 +2477,7 @@ void tr_peerMgr::reconnectPulse()
{
using namespace disconnect_helpers;
auto const lock = session->unique_lock();
auto const now_sec = tr_time();
// remove crappy peers

View File

@ -44,79 +44,96 @@ public:
[[nodiscard]] value_type& operator*() noexcept
{
return *reinterpret_cast<value_type*>(iov_.iov_base);
return reinterpret_cast<value_type*>(iov_.iov_base)[iov_offset_];
}
[[nodiscard]] value_type operator*() const noexcept
{
return *reinterpret_cast<value_type*>(iov_.iov_base);
return reinterpret_cast<value_type*>(iov_.iov_base)[iov_offset_];
}
[[nodiscard]] Iterator operator+(int n_bytes)
[[nodiscard]] Iterator operator+(size_t n_bytes)
{
return Iterator(buf_, offset_ + n_bytes);
return Iterator{ buf_, offset() + n_bytes };
}
[[nodiscard]] Iterator operator-(int n_bytes)
[[nodiscard]] Iterator operator-(size_t n_bytes)
{
return Iterator(buf_, offset_ - n_bytes);
return Iterator{ buf_, offset() - n_bytes };
}
[[nodiscard]] constexpr auto operator-(Iterator const& that) const noexcept
{
return offset_ - that.offset_;
return offset() - that.offset();
}
Iterator& operator++() noexcept
{
if (iov_.iov_len > 1)
{
iov_.iov_base = reinterpret_cast<value_type*>(iov_.iov_base) + 1;
--iov_.iov_len;
++offset_;
}
else
{
setOffset(offset_ + 1);
}
*this += 1U;
return *this;
}
Iterator& operator+=(int n_bytes)
Iterator& operator+=(size_t n_bytes)
{
setOffset(offset_ + n_bytes);
if (iov_offset_ + n_bytes < iov_.iov_len)
{
iov_offset_ += n_bytes;
}
else
{
incOffset(n_bytes);
}
return *this;
}
Iterator& operator--() noexcept
{
// TODO(ckerr) inefficient; calls evbuffer_ptr_peek() every time
setOffset(offset_ - 1);
if (iov_offset_ > 0)
{
--iov_offset_;
}
else
{
setOffset(offset() - 1);
}
return *this;
}
[[nodiscard]] constexpr bool operator==(Iterator const& that) const noexcept
{
return offset_ == that.offset_;
return offset() == that.offset();
}
[[nodiscard]] constexpr bool operator!=(Iterator const& that) const noexcept
{
return !(*this == that);
return offset() != that.offset();
}
private:
[[nodiscard]] constexpr size_t offset() const noexcept
{
return ptr_.pos + iov_offset_;
}
void incOffset(size_t increment)
{
evbuffer_ptr_set(buf_, &ptr_, iov_offset_ + increment, EVBUFFER_PTR_ADD);
evbuffer_peek(buf_, std::numeric_limits<ev_ssize_t>::max(), &ptr_, &iov_, 1);
iov_offset_ = 0;
}
void setOffset(size_t offset)
{
offset_ = offset;
auto ptr = evbuffer_ptr{};
evbuffer_ptr_set(buf_, &ptr, offset, EVBUFFER_PTR_SET);
evbuffer_peek(buf_, std::numeric_limits<ev_ssize_t>::max(), &ptr, &iov_, 1);
evbuffer_ptr_set(buf_, &ptr_, offset, EVBUFFER_PTR_SET);
evbuffer_peek(buf_, std::numeric_limits<ev_ssize_t>::max(), &ptr_, &iov_, 1);
iov_offset_ = 0;
}
evbuffer* buf_;
evbuffer_ptr ptr_ = {};
Iovec iov_ = {};
size_t offset_ = 0;
size_t iov_offset_ = 0;
};
Buffer() = default;
@ -351,11 +368,8 @@ public:
[[nodiscard]] std::string toString() const
{
auto str = std::string{};
str.reserve(size());
for (auto const& by : *this)
{
str.push_back(*reinterpret_cast<char const*>(&by));
}
str.resize(size());
evbuffer_copyout(buf_.get(), std::data(str), std::size(str));
return str;
}