Index: components/password_manager/core/browser/password_store_unittest.cc |
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc |
index 681d0421ef5b5cf854137a2712a6c78eac0b2b2f..4507775884faa5c71275ce3428cf33765ae65aad 100644 |
--- a/components/password_manager/core/browser/password_store_unittest.cc |
+++ b/components/password_manager/core/browser/password_store_unittest.cc |
@@ -2,6 +2,8 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include <memory> |
+ |
#include "base/basictypes.h" |
#include "base/bind.h" |
#include "base/files/scoped_temp_dir.h" |
@@ -210,4 +212,158 @@ TEST_F(PasswordStoreTest, StartSyncFlare) { |
base::MessageLoop::current()->RunUntilIdle(); |
} |
+template <typename FormMover> |
+inline void MoveAllFormsOut(ScopedVector<autofill::PasswordForm>* forms, |
+ FormMover mover) { |
+ for (auto* form_ptr : *forms) { |
+ scoped_ptr<autofill::PasswordForm> form(form_ptr); |
+ mover(form.Pass()); |
+ } |
+ forms->weak_clear(); |
+} |
+ |
+template <typename FormMover> |
+inline void MoveAllFormsOutNoScopedPtr( |
+ ScopedVector<autofill::PasswordForm>* forms, |
+ FormMover mover) { |
+ for (auto* form_ptr : *forms) { |
+ mover(form_ptr); |
+ } |
+ forms->weak_clear(); |
+} |
+ |
+TEST(Vabr, Vabr) { |
+ // First, do one loop without measuring. This is a warm-up and |
+ // should ensure that memory caches and similar things do not |
+ // skew the results. |
+ for (unsigned size_shift = 3; size_shift < 20; ++size_shift) { |
+ const size_t size = 1 << size_shift; |
+ std::vector<autofill::PasswordForm*> v(size, nullptr); |
+ ScopedVector<autofill::PasswordForm> target; |
+ { |
+ ScopedVector<autofill::PasswordForm> source; |
+ source.swap(v); // Fill up the source. |
+ // Do not let allocation mess up the timing. |
+ target.reserve(source.size()); |
+ |
+ MoveAllFormsOut(&source, |
+ [&target](scoped_ptr<autofill::PasswordForm> form) { |
+ target.push_back(form.release()); |
+ }); |
+ } |
+ } |
+ for (unsigned size_shift = 3; size_shift < 20; ++size_shift) { |
+ const size_t size = 1 << size_shift; |
+ std::vector<autofill::PasswordForm*> v(size, nullptr); |
+ ScopedVector<autofill::PasswordForm> target; |
+ base::TimeTicks t; |
+ { |
+ ScopedVector<autofill::PasswordForm> source; |
+ source.swap(v); // Fill up the source. |
+ // Do not let allocation mess up the timing. |
+ target.reserve(source.size()); |
+ |
+ t = base::TimeTicks::Now(); |
+ for (auto* form_ptr : source) { |
+ target.push_back(form_ptr); |
+ } |
+ source.weak_clear(); |
+ } |
+ base::TimeDelta elapsed = base::TimeTicks::Now() - t; |
+ |
+ LOG(INFO) << "For size=" << size << ", inline, elapsed " |
+ << elapsed.InMicroseconds() << "us"; |
+ } |
+ for (unsigned size_shift = 3; size_shift < 20; ++size_shift) { |
+ const size_t size = 1 << size_shift; |
+ std::vector<autofill::PasswordForm*> v(size, nullptr); |
+ ScopedVector<autofill::PasswordForm> target; |
+ base::TimeTicks t; |
+ { |
+ ScopedVector<autofill::PasswordForm> source; |
+ source.swap(v); // Fill up the source. |
+ // Do not let allocation mess up the timing. |
+ target.reserve(source.size()); |
+ |
+ t = base::TimeTicks::Now(); |
+ MoveAllFormsOutNoScopedPtr(&source, |
+ [&target](autofill::PasswordForm* form_ptr) { |
+ scoped_ptr<autofill::PasswordForm> form(form_ptr); |
+ target.push_back(form.release()); |
+ }); |
+ } |
+ base::TimeDelta elapsed = base::TimeTicks::Now() - t; |
+ |
+ LOG(INFO) << "For size=" << size << ", LAMBDAS+local scoped_ptr, elapsed " |
+ << elapsed.InMicroseconds() << "us"; |
+ } |
+ for (unsigned size_shift = 3; size_shift < 20; ++size_shift) { |
+ const size_t size = 1 << size_shift; |
+ std::vector<autofill::PasswordForm*> v(size, nullptr); |
+ ScopedVector<autofill::PasswordForm> target; |
+ base::TimeTicks t; |
+ { |
+ ScopedVector<autofill::PasswordForm> source; |
+ source.swap(v); // Fill up the source. |
+ // Do not let allocation mess up the timing. |
+ target.reserve(source.size()); |
+ |
+ t = base::TimeTicks::Now(); |
+ MoveAllFormsOutNoScopedPtr( |
+ &source, |
+ [&target](autofill::PasswordForm* form) { target.push_back(form); }); |
+ } |
+ base::TimeDelta elapsed = base::TimeTicks::Now() - t; |
+ |
+ LOG(INFO) << "For size=" << size << ", LAMBDAS+naked pointers, elapsed " |
+ << elapsed.InMicroseconds() << "us"; |
+ } |
+#if 0 |
+ for (unsigned size_shift = 3; size_shift < 20; ++size_shift) { |
+ const size_t size = 1 << size_shift; |
+ std::vector<autofill::PasswordForm*> v(size, nullptr); |
+ ScopedVector<autofill::PasswordForm> target; |
+ base::TimeTicks t; |
+ { |
+ ScopedVector<autofill::PasswordForm> source; |
+ source.swap(v); // Fill up the source. |
+ // Do not let allocation mess up the timing. |
+ target.reserve(source.size()); |
+ |
+ t = base::TimeTicks::Now(); |
+ MoveAllFormsOutNoScopedPtr( |
+ &source, [&target](std::unique_ptr<autofill::PasswordForm> form) { |
+ target.push_back(form.release()); |
+ }); |
+ } |
+ base::TimeDelta elapsed = base::TimeTicks::Now() - t; |
+ |
+ LOG(INFO) << "For size=" << size << ", LAMBDAS+unique_ptr, elapsed " |
+ << elapsed.InMicroseconds() << "us"; |
+ } |
+#endif |
+ for (unsigned size_shift = 3; size_shift < 20; ++size_shift) { |
+ const size_t size = 1 << size_shift; |
+ std::vector<autofill::PasswordForm*> v(size, nullptr); |
+ ScopedVector<autofill::PasswordForm> target; |
+ base::TimeTicks t; |
+ { |
+ ScopedVector<autofill::PasswordForm> source; |
+ source.swap(v); // Fill up the source. |
+ // Do not let allocation mess up the timing. |
+ target.reserve(source.size()); |
+ |
+ t = base::TimeTicks::Now(); |
+ MoveAllFormsOut(&source, |
+ [&target](scoped_ptr<autofill::PasswordForm> form) { |
+ target.push_back(form.release()); |
+ }); |
+ } |
+ base::TimeDelta elapsed = base::TimeTicks::Now() - t; |
+ |
+ LOG(INFO) << "For size=" << size << ", LAMBDAS+scoped_ptr, elapsed " |
+ << elapsed.InMicroseconds() << "us"; |
+ } |
+} |
+ |
} // namespace password_manager |