diff options
author | Karol Kosek <krkk@serenityos.org> | 2021-09-25 20:40:02 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-27 16:31:28 +0200 |
commit | 484f6a7cfa9129a221ec21ed0567c69a7abab7b2 (patch) | |
tree | edda84827d1b0398a9034c68502cc544a642b22f | |
parent | 48a925b1d23003565da44bcd74029d1eef714dee (diff) | |
download | serenity-484f6a7cfa9129a221ec21ed0567c69a7abab7b2.zip |
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.
-rw-r--r-- | Userland/Libraries/LibCore/IODevice.cpp | 51 |
1 files changed, 19 insertions, 32 deletions
diff --git a/Userland/Libraries/LibCore/IODevice.cpp b/Userland/Libraries/LibCore/IODevice.cpp index 686d75ea84..6e1c16c270 100644 --- a/Userland/Libraries/LibCore/IODevice.cpp +++ b/Userland/Libraries/LibCore/IODevice.cpp @@ -43,44 +43,31 @@ ByteBuffer IODevice::read(size_t max_size) return {}; if (!max_size) 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()) { dbgln("IODevice::read: Not enough memory to allocate a buffer of {} bytes", max_size); return {}; } auto buffer = buffer_result.release_value(); auto* buffer_ptr = (char*)buffer.data(); - size_t remaining_buffer_space = buffer.size(); - size_t taken_from_buffered = 0; - if (!m_buffered_data.is_empty()) { - 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); + + memcpy(buffer_ptr, m_buffered_data.data(), size); + m_buffered_data.remove(0, size); + return buffer; } |