mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
util: improve streams.h:FindByte() performance
Avoid use of the expensive mod operator (%) when calculating the buffer offset. No functional difference. Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
This commit is contained in:
parent
604df63f6c
commit
72efc26439
5 changed files with 19 additions and 9 deletions
|
@ -20,7 +20,7 @@ static void FindByte(benchmark::Bench& bench)
|
||||||
|
|
||||||
bench.run([&] {
|
bench.run([&] {
|
||||||
bf.SetPos(0);
|
bf.SetPos(0);
|
||||||
bf.FindByte(1);
|
bf.FindByte(std::byte(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
|
|
@ -756,15 +756,25 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//! search for a given byte in the stream, and remain positioned on it
|
//! search for a given byte in the stream, and remain positioned on it
|
||||||
void FindByte(uint8_t ch)
|
void FindByte(std::byte byte)
|
||||||
{
|
{
|
||||||
|
// For best performance, avoid mod operation within the loop.
|
||||||
|
size_t buf_offset{size_t(m_read_pos % uint64_t(vchBuf.size()))};
|
||||||
while (true) {
|
while (true) {
|
||||||
if (m_read_pos == nSrcPos)
|
if (m_read_pos == nSrcPos) {
|
||||||
|
// No more bytes available; read from the file into the buffer,
|
||||||
|
// setting nSrcPos to one beyond the end of the new data.
|
||||||
|
// Throws exception if end-of-file reached.
|
||||||
Fill();
|
Fill();
|
||||||
if (vchBuf[m_read_pos % vchBuf.size()] == std::byte{ch}) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
m_read_pos++;
|
const size_t len{std::min<size_t>(vchBuf.size() - buf_offset, nSrcPos - m_read_pos)};
|
||||||
|
const auto it_start{vchBuf.begin() + buf_offset};
|
||||||
|
const auto it_find{std::find(it_start, it_start + len, byte)};
|
||||||
|
const size_t inc{size_t(std::distance(it_start, it_find))};
|
||||||
|
m_read_pos += inc;
|
||||||
|
if (inc < len) break;
|
||||||
|
buf_offset += inc;
|
||||||
|
if (buf_offset >= vchBuf.size()) buf_offset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,7 +53,7 @@ FUZZ_TARGET(buffered_file)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
opt_buffered_file->FindByte(fuzzed_data_provider.ConsumeIntegral<uint8_t>());
|
opt_buffered_file->FindByte(std::byte(fuzzed_data_provider.ConsumeIntegral<uint8_t>()));
|
||||||
} catch (const std::ios_base::failure&) {
|
} catch (const std::ios_base::failure&) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
|
||||||
size_t find = currentPos + InsecureRandRange(8);
|
size_t find = currentPos + InsecureRandRange(8);
|
||||||
if (find >= fileSize)
|
if (find >= fileSize)
|
||||||
find = fileSize - 1;
|
find = fileSize - 1;
|
||||||
bf.FindByte(uint8_t(find));
|
bf.FindByte(std::byte(find));
|
||||||
// The value at each offset is the offset.
|
// The value at each offset is the offset.
|
||||||
BOOST_CHECK_EQUAL(bf.GetPos(), find);
|
BOOST_CHECK_EQUAL(bf.GetPos(), find);
|
||||||
currentPos = find;
|
currentPos = find;
|
||||||
|
|
|
@ -4565,7 +4565,7 @@ void Chainstate::LoadExternalBlockFile(
|
||||||
try {
|
try {
|
||||||
// locate a header
|
// locate a header
|
||||||
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
|
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
|
||||||
blkdat.FindByte(params.MessageStart()[0]);
|
blkdat.FindByte(std::byte(params.MessageStart()[0]));
|
||||||
nRewind = blkdat.GetPos() + 1;
|
nRewind = blkdat.GetPos() + 1;
|
||||||
blkdat >> buf;
|
blkdat >> buf;
|
||||||
if (memcmp(buf, params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
|
if (memcmp(buf, params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue