mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:47:35 +00:00
LibCore: Buffer small byte reads
Prior this change, if you had a program which frequently reads small amount of bytes, then it would constantly fire up syscalls. This patch sets that the minimum size that is passed to the read syscall is 1024 and then it saves these additional bytes in a buffer for next reads, which greatly improves the cpu usage on such cases. In other words: reading flacs is now very efficient.
This commit is contained in:
parent
48a925b1d2
commit
484f6a7cfa
1 changed files with 19 additions and 32 deletions
|
@ -43,44 +43,31 @@ ByteBuffer IODevice::read(size_t max_size)
|
||||||
return {};
|
return {};
|
||||||
if (!max_size)
|
if (!max_size)
|
||||||
return {};
|
return {};
|
||||||
auto buffer_result = ByteBuffer::create_uninitialized(max_size);
|
|
||||||
|
if (m_buffered_data.size() < max_size)
|
||||||
|
populate_read_buffer(max(max_size - m_buffered_data.size(), 1024));
|
||||||
|
|
||||||
|
if (m_buffered_data.size() > max_size) {
|
||||||
|
if (m_error)
|
||||||
|
return {};
|
||||||
|
if (m_eof) {
|
||||||
|
dbgln("IODevice::read: At EOF but there's more than max_size({}) buffered", max_size);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto size = min(max_size, m_buffered_data.size());
|
||||||
|
auto buffer_result = ByteBuffer::create_uninitialized(size);
|
||||||
if (!buffer_result.has_value()) {
|
if (!buffer_result.has_value()) {
|
||||||
dbgln("IODevice::read: Not enough memory to allocate a buffer of {} bytes", max_size);
|
dbgln("IODevice::read: Not enough memory to allocate a buffer of {} bytes", max_size);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto buffer = buffer_result.release_value();
|
auto buffer = buffer_result.release_value();
|
||||||
auto* buffer_ptr = (char*)buffer.data();
|
auto* buffer_ptr = (char*)buffer.data();
|
||||||
size_t remaining_buffer_space = buffer.size();
|
|
||||||
size_t taken_from_buffered = 0;
|
memcpy(buffer_ptr, m_buffered_data.data(), size);
|
||||||
if (!m_buffered_data.is_empty()) {
|
m_buffered_data.remove(0, size);
|
||||||
taken_from_buffered = min(remaining_buffer_space, m_buffered_data.size());
|
|
||||||
memcpy(buffer_ptr, m_buffered_data.data(), taken_from_buffered);
|
|
||||||
Vector<u8> new_buffered_data;
|
|
||||||
new_buffered_data.append(m_buffered_data.data() + taken_from_buffered, m_buffered_data.size() - taken_from_buffered);
|
|
||||||
m_buffered_data = move(new_buffered_data);
|
|
||||||
remaining_buffer_space -= taken_from_buffered;
|
|
||||||
buffer_ptr += taken_from_buffered;
|
|
||||||
}
|
|
||||||
if (!remaining_buffer_space)
|
|
||||||
return buffer;
|
|
||||||
int nread = ::read(m_fd, buffer_ptr, remaining_buffer_space);
|
|
||||||
if (nread < 0) {
|
|
||||||
if (taken_from_buffered) {
|
|
||||||
buffer.resize(taken_from_buffered);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
set_error(errno);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (nread == 0) {
|
|
||||||
set_eof(true);
|
|
||||||
if (taken_from_buffered) {
|
|
||||||
buffer.resize(taken_from_buffered);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
buffer.resize(taken_from_buffered + nread);
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue