Index: net/disk_cache/disk_cache_perftest.cc |
diff --git a/net/disk_cache/disk_cache_perftest.cc b/net/disk_cache/disk_cache_perftest.cc |
index c8df0df37d693a7d214144698c9b036059d55a65..52667df95aad99667641f07881cd9b36a63ca966 100644 |
--- a/net/disk_cache/disk_cache_perftest.cc |
+++ b/net/disk_cache/disk_cache_perftest.cc |
@@ -5,6 +5,7 @@ |
#include <limits> |
#include <string> |
+#include "base/barrier_closure.h" |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
#include "base/files/file_enumerator.h" |
@@ -13,6 +14,7 @@ |
#include "base/process/process_metrics.h" |
#include "base/rand_util.h" |
#include "base/run_loop.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_util.h" |
#include "base/test/perf_time_logger.h" |
#include "base/test/scoped_task_environment.h" |
@@ -302,6 +304,89 @@ TEST_F(DiskCachePerfTest, BlockFilesPerformance) { |
base::RunLoop().RunUntilIdle(); |
} |
+void VerifyRvAndCallClosure(base::Closure* c, int expect_rv, int rv) { |
+ EXPECT_EQ(expect_rv, rv); |
+ c->Run(); |
+} |
+ |
+TEST_F(DiskCachePerfTest, SimpleCacheInitialReadPortion) { |
+ // A benchmark that aims to measure how much time we take in I/O thread |
+ // for initial bookkeeping before returning to the caller, and how much |
+ // after (batched up some). The later portion includes some event loop |
+ // overhead. |
+ const int kBatchSize = 100; |
+ |
+ SetSimpleCacheMode(); |
+ |
+ InitCache(); |
+ // Write out the entries, and keep their objects around. |
+ scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kHeadersSize)); |
+ scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kBodySize)); |
+ |
+ CacheTestFillBuffer(buffer1->data(), kHeadersSize, false); |
+ CacheTestFillBuffer(buffer2->data(), kBodySize, false); |
+ |
+ disk_cache::Entry* cache_entry[kBatchSize]; |
+ for (int i = 0; i < kBatchSize; ++i) { |
+ net::TestCompletionCallback cb; |
+ int rv = cache_->CreateEntry(base::IntToString(i), &cache_entry[i], |
+ cb.callback()); |
+ ASSERT_EQ(net::OK, cb.GetResult(rv)); |
+ |
+ rv = cache_entry[i]->WriteData(0, 0, buffer1.get(), kHeadersSize, |
+ cb.callback(), false); |
+ ASSERT_EQ(kHeadersSize, cb.GetResult(rv)); |
+ rv = cache_entry[i]->WriteData(1, 0, buffer2.get(), kBodySize, |
+ cb.callback(), false); |
+ ASSERT_EQ(kBodySize, cb.GetResult(rv)); |
+ } |
+ |
+ // Now repeatedly read these, batching up the waiting to try to |
+ // account for the two portions separately. Note that we need separate entries |
+ // since we are trying to keep interesting work from being on the delayed-done |
+ // portion. |
+ const int kIterations = 50000; |
+ |
+ double elapsed_early = 0.0; |
+ double elapsed_late = 0.0; |
+ |
+ for (int i = 0; i < kIterations; ++i) { |
+ base::RunLoop event_loop; |
+ base::Closure barrier = |
+ base::BarrierClosure(kBatchSize, event_loop.QuitWhenIdleClosure()); |
+ net::CompletionCallback cb_batch(base::Bind( |
+ VerifyRvAndCallClosure, base::Unretained(&barrier), kHeadersSize)); |
+ |
+ base::ElapsedTimer timer_early; |
+ for (int e = 0; e < kBatchSize; ++e) { |
+ int rv = |
+ cache_entry[e]->ReadData(0, 0, buffer1.get(), kHeadersSize, cb_batch); |
+ if (rv != net::ERR_IO_PENDING) { |
+ barrier.Run(); |
+ ASSERT_EQ(kHeadersSize, rv); |
+ } |
+ } |
+ elapsed_early += timer_early.Elapsed().InMillisecondsF(); |
+ |
+ base::ElapsedTimer timer_late; |
+ event_loop.Run(); |
+ elapsed_late += timer_late.Elapsed().InMillisecondsF(); |
+ } |
+ |
+ // Cleanup |
+ for (int i = 0; i < kBatchSize; ++i) |
+ cache_entry[i]->Close(); |
+ |
+ disk_cache::SimpleBackendImpl::FlushWorkerPoolForTesting(); |
+ base::RunLoop().RunUntilIdle(); |
+ LOG(ERROR) << "Early portion:" << elapsed_early << " ms"; |
+ LOG(ERROR) << "\tPer entry:" |
+ << 1000 * (elapsed_early / (kIterations * kBatchSize)) << " us"; |
+ LOG(ERROR) << "Event loop portion: " << elapsed_late << " ms"; |
+ LOG(ERROR) << "\tPer entry:" |
+ << 1000 * (elapsed_late / (kIterations * kBatchSize)) << " us"; |
+} |
+ |
// Measures how quickly SimpleIndex can compute which entries to evict. |
TEST(SimpleIndexPerfTest, EvictionPerformance) { |
const int kEntries = 10000; |