diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-23 17:39:53 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-23 17:39:53 +0000 |
commit | db2fb782473f73581430e16df9b1bd8b15e8e85c (patch) | |
tree | 7e3a3a0234a2484b3ef1a313f7fde72da8ab4b17 /chrome | |
parent | f1cd5e88af6f0d088d7b90a8f4b69da63aa994af (diff) | |
download | chromium_src-db2fb782473f73581430e16df9b1bd8b15e8e85c.zip chromium_src-db2fb782473f73581430e16df9b1bd8b15e8e85c.tar.gz chromium_src-db2fb782473f73581430e16df9b1bd8b15e8e85c.tar.bz2 |
When sending resources across the IPC barrier, use increasing sized buffers.
AsyncResourceHandler::OnWillRead will usually allocate a new piece of shared
memory for each 32 kilobyte chunk of a resource to be sent over IPC from the
browser to the renderer. Instead, use a 32k chunk, then a 64k chunk, then a
128k chunk up to a maximum size of 512k.
Why? Because transferring large resources is really slow. To send a sequence of
32k chunks to the renderer, we need to wait for the renderer to send an ACK
message back before we send the next chunk.
The themeing on the new tab page is a pathological case for this code. Most of
the background images are large, and my test case is about 800k. This was 25
round trips. Now it is 5. According to the web inspector, it used to take ~700ms to transfer said image. Now
it's in the ~30ms range. It feels faster, and the web inspector shows the speed up, but tab_complex_theme_cold does not...
BUG=http://crbug.com/24493
TEST=Doesn't regress any performance tests.
Review URL: http://codereview.chromium.org/331001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29904 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/renderer_host/async_resource_handler.cc | 40 | ||||
-rw-r--r-- | chrome/browser/renderer_host/async_resource_handler.h | 6 |
2 files changed, 38 insertions, 8 deletions
diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index 95852be..da188b6 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -10,15 +10,28 @@ #include "chrome/common/render_messages.h" #include "net/base/io_buffer.h" +namespace { + // When reading, we don't know if we are going to get EOF (0 bytes read), so // we typically have a buffer that we allocated but did not use. We keep // this buffer around for the next read as a small optimization. -static SharedIOBuffer* g_spare_read_buffer = NULL; +SharedIOBuffer* g_spare_read_buffer = NULL; + +// The initial size of the shared memory buffer. (32 kilobytes). +const int kReadBufSize = 32768; + +// The maximum size of the shared memory buffer. (512 kilobytes). +const int kMaxBufSize = 524288; + +} // namespace // Our version of IOBuffer that uses shared memory. class SharedIOBuffer : public net::IOBuffer { public: - SharedIOBuffer(int buffer_size) : net::IOBuffer(), ok_(false) { + SharedIOBuffer(int buffer_size) + : net::IOBuffer(), + ok_(false), + buffer_size_(buffer_size) { if (shared_memory_.Create(std::wstring(), false, false, buffer_size) && shared_memory_.Map(buffer_size)) { ok_ = true; @@ -33,10 +46,12 @@ class SharedIOBuffer : public net::IOBuffer { base::SharedMemory* shared_memory() { return &shared_memory_; } bool ok() { return ok_; } + int buffer_size() { return buffer_size_; } private: base::SharedMemory shared_memory_; bool ok_; + int buffer_size_; }; AsyncResourceHandler::AsyncResourceHandler( @@ -50,7 +65,8 @@ AsyncResourceHandler::AsyncResourceHandler( process_id_(process_id), routing_id_(routing_id), process_handle_(process_handle), - rdh_(resource_dispatcher_host) { + rdh_(resource_dispatcher_host), + next_buffer_size_(kReadBufSize) { } bool AsyncResourceHandler::OnUploadProgress(int request_id, @@ -80,21 +96,29 @@ bool AsyncResourceHandler::OnResponseStarted(int request_id, bool AsyncResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size, int min_size) { DCHECK(min_size == -1); - static const int kReadBufSize = 32768; + if (g_spare_read_buffer) { DCHECK(!read_buffer_); read_buffer_.swap(&g_spare_read_buffer); // TODO(willchan): Remove after debugging bug 16371. CHECK(read_buffer_->data()); + + *buf = read_buffer_.get(); + *buf_size = read_buffer_.get()->buffer_size(); } else { - read_buffer_ = new SharedIOBuffer(kReadBufSize); - if (!read_buffer_->ok()) + read_buffer_ = new SharedIOBuffer(next_buffer_size_); + if (!read_buffer_->ok()) { + DLOG(ERROR) << "Couldn't allocate shared io buffer"; return false; + } // TODO(willchan): Remove after debugging bug 16371. CHECK(read_buffer_->data()); + *buf = read_buffer_.get(); + *buf_size = next_buffer_size_; } - *buf = read_buffer_.get(); - *buf_size = kReadBufSize; + + next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxBufSize); + return true; } diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h index 17e9260..b946d4d 100644 --- a/chrome/browser/renderer_host/async_resource_handler.h +++ b/chrome/browser/renderer_host/async_resource_handler.h @@ -46,6 +46,12 @@ class AsyncResourceHandler : public ResourceHandler { base::ProcessHandle process_handle_; ResourceDispatcherHost* rdh_; + // We exponentially grow the size of the buffer allocated. On the first + // OnWillRead() call, we allocate a buffer of 32k and double it on each + // subsequent call, up to a maximum size of 512k. |next_buffer_size_| is the + // size of the buffer to be allocated on the next OnWillRead() call. + int next_buffer_size_; + DISALLOW_COPY_AND_ASSIGN(AsyncResourceHandler); }; |