Commit 086da203 authored by mball@google.com's avatar mball@google.com

Merged in NaCl SDK r1388 from old repo

Original commit text:

Add some suggested performance improvements to geturl.

Original Review URL: http://codereview.chromium.org/8603014

BUG=None
TEST=None
TBR=bradnelson@chromium.org

Review URL: http://codereview.chromium.org/8922018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114125 0039d316-1c4b-4281-b951-d872f2087c98
parent 1f82b3d1
...@@ -28,12 +28,16 @@ GetURLHandler::GetURLHandler(pp::Instance* instance, ...@@ -28,12 +28,16 @@ GetURLHandler::GetURLHandler(pp::Instance* instance,
url_(url), url_(url),
url_request_(instance), url_request_(instance),
url_loader_(instance), url_loader_(instance),
buffer_(new char[READ_BUFFER_SIZE]),
cc_factory_(this) { cc_factory_(this) {
url_request_.SetURL(url); url_request_.SetURL(url);
url_request_.SetMethod("GET"); url_request_.SetMethod("GET");
url_request_.SetRecordDownloadProgress(true);
} }
GetURLHandler::~GetURLHandler() { GetURLHandler::~GetURLHandler() {
delete [] buffer_;
buffer_ = NULL;
} }
void GetURLHandler::Start() { void GetURLHandler::Start() {
...@@ -51,6 +55,23 @@ void GetURLHandler::OnOpen(int32_t result) { ...@@ -51,6 +55,23 @@ void GetURLHandler::OnOpen(int32_t result) {
// check the HTTP code and potentially cancel the request. // check the HTTP code and potentially cancel the request.
// pp::URLResponseInfo response = loader_.GetResponseInfo(); // pp::URLResponseInfo response = loader_.GetResponseInfo();
// Try to figure out how many bytes of data are going to be downloaded in
// order to allocate memory for the response body in advance (this will
// reduce heap traffic and also the amount of memory allocated).
// It is not a problem if this fails, it just means that the
// url_response_body_.insert() call in GetURLHandler::AppendDataBytes()
// will allocate the memory later on.
int64_t bytes_received = 0;
int64_t total_bytes_to_be_received = 0;
if (url_loader_.GetDownloadProgress(&bytes_received,
&total_bytes_to_be_received)) {
if (total_bytes_to_be_received > 0) {
url_response_body_.reserve(total_bytes_to_be_received);
}
}
// We will not use the download progress anymore, so just disable it.
url_request_.SetRecordDownloadProgress(false);
// Start streaming. // Start streaming.
ReadBody(); ReadBody();
} }
...@@ -60,7 +81,9 @@ void GetURLHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) { ...@@ -60,7 +81,9 @@ void GetURLHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) {
return; return;
// Make sure we don't get a buffer overrun. // Make sure we don't get a buffer overrun.
num_bytes = std::min(READ_BUFFER_SIZE, num_bytes); num_bytes = std::min(READ_BUFFER_SIZE, num_bytes);
url_response_body_.reserve(url_response_body_.size() + num_bytes); // Note that we do *not* try to minimally increase the amount of allocated
// memory here by calling url_response_body_.reserve(). Doing so causes a
// lot of string reallocations that kills performance for large files.
url_response_body_.insert(url_response_body_.end(), url_response_body_.insert(url_response_body_.end(),
buffer, buffer,
buffer + num_bytes); buffer + num_bytes);
...@@ -68,7 +91,10 @@ void GetURLHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) { ...@@ -68,7 +91,10 @@ void GetURLHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) {
void GetURLHandler::OnRead(int32_t result) { void GetURLHandler::OnRead(int32_t result) {
if (result == PP_OK) { if (result == PP_OK) {
// Streaming the file is complete. // Streaming the file is complete, delete the read buffer since it is
// no longer needed.
delete [] buffer_;
buffer_ = NULL;
ReportResultAndDie(url_, url_response_body_, true); ReportResultAndDie(url_, url_response_body_, true);
} else if (result > 0) { } else if (result > 0) {
// The URLLoader just filled "result" number of bytes into our buffer. // The URLLoader just filled "result" number of bytes into our buffer.
...@@ -94,7 +120,7 @@ void GetURLHandler::ReadBody() { ...@@ -94,7 +120,7 @@ void GetURLHandler::ReadBody() {
cc_factory_.NewOptionalCallback(&GetURLHandler::OnRead); cc_factory_.NewOptionalCallback(&GetURLHandler::OnRead);
int32_t result = PP_OK; int32_t result = PP_OK;
do { do {
result = url_loader_.ReadResponseBody(buffer_, sizeof(buffer_), cc); result = url_loader_.ReadResponseBody(buffer_, READ_BUFFER_SIZE, cc);
// Handle streaming data directly. Note that we *don't* want to call // Handle streaming data directly. Note that we *don't* want to call
// OnRead here, since in the case of result > 0 it will schedule // OnRead here, since in the case of result > 0 it will schedule
// another call to this function. If the network is very fast, we could // another call to this function. If the network is very fast, we could
......
...@@ -11,12 +11,20 @@ ...@@ -11,12 +11,20 @@
#include "ppapi/cpp/url_request_info.h" #include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/instance.h" #include "ppapi/cpp/instance.h"
#define READ_BUFFER_SIZE 4096 #define READ_BUFFER_SIZE 32768
// GetURLHandler is used to download data from |url|. When download is // GetURLHandler is used to download data from |url|. When download is
// finished or when an error occurs, it posts a message back to the browser // finished or when an error occurs, it posts a message back to the browser
// with the results encoded in the message as a string and self-destroys. // with the results encoded in the message as a string and self-destroys.
// //
// pp::URLLoader.GetDownloadProgress() is used to to allocate the memory
// required for url_response_body_ before the download starts. (This is not so
// much of a performance improvement, but it saves some memory since
// std::string.insert() typically grows the string's capacity by somewhere
// between 50% to 100% when it needs more memory, depending on the
// implementation.) Other performance improvements made as outlined in this
// bug: http://code.google.com/p/chromium/issues/detail?id=103947
//
// EXAMPLE USAGE: // EXAMPLE USAGE:
// GetURLHandler* handler* = GetURLHandler::Create(instance,url); // GetURLHandler* handler* = GetURLHandler::Create(instance,url);
// handler->Start(); // handler->Start();
...@@ -69,7 +77,7 @@ class GetURLHandler { ...@@ -69,7 +77,7 @@ class GetURLHandler {
std::string url_; // URL to be downloaded. std::string url_; // URL to be downloaded.
pp::URLRequestInfo url_request_; pp::URLRequestInfo url_request_;
pp::URLLoader url_loader_; // URLLoader provides an API to download URLs. pp::URLLoader url_loader_; // URLLoader provides an API to download URLs.
char buffer_[READ_BUFFER_SIZE]; // Temporary buffer for reads. char* buffer_; // Temporary buffer for reads.
std::string url_response_body_; // Contains accumulated downloaded data. std::string url_response_body_; // Contains accumulated downloaded data.
pp::CompletionCallbackFactory<GetURLHandler> cc_factory_; pp::CompletionCallbackFactory<GetURLHandler> cc_factory_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment