diff --git a/cef_paths2.gypi b/cef_paths2.gypi index 17e264340..79a854137 100644 --- a/cef_paths2.gypi +++ b/cef_paths2.gypi @@ -98,11 +98,16 @@ 'tests/cefclient/dialog_test.h', 'tests/cefclient/dom_test.cpp', 'tests/cefclient/dom_test.h', + 'tests/cefclient/performance_test.cpp', + 'tests/cefclient/performance_test.h', + 'tests/cefclient/performance_test_setup.h', + 'tests/cefclient/performance_test_tests.cpp', 'tests/cefclient/res/binding.html', 'tests/cefclient/res/dialogs.html', 'tests/cefclient/res/domaccess.html', 'tests/cefclient/res/localstorage.html', 'tests/cefclient/res/logo.png', + 'tests/cefclient/res/performance.html', 'tests/cefclient/res/xmlhttprequest.html', 'tests/cefclient/resource_util.h', 'tests/cefclient/scheme_test.cpp', @@ -143,6 +148,10 @@ 'tests/cefclient/dialog_test.h', 'tests/cefclient/dom_test.cpp', 'tests/cefclient/dom_test.h', + 'tests/cefclient/performance_test.cpp', + 'tests/cefclient/performance_test.h', + 'tests/cefclient/performance_test_setup.h', + 'tests/cefclient/performance_test_tests.cpp', 'tests/cefclient/process_helper_mac.cpp', 'tests/cefclient/resource_util.h', 'tests/cefclient/resource_util_mac.mm', @@ -162,6 +171,7 @@ 'tests/cefclient/res/domaccess.html', 'tests/cefclient/res/localstorage.html', 'tests/cefclient/res/logo.png', + 'tests/cefclient/res/performance.html', 'tests/cefclient/res/xmlhttprequest.html', ], 'cefclient_sources_linux': [ @@ -175,6 +185,7 @@ 'tests/cefclient/res/domaccess.html', 'tests/cefclient/res/localstorage.html', 'tests/cefclient/res/logo.png', + 'tests/cefclient/res/performance.html', 'tests/cefclient/res/xmlhttprequest.html', ], }, diff --git a/include/internal/cef_time.h b/include/internal/cef_time.h index ccaf19320..64e601fe0 100644 --- a/include/internal/cef_time.h +++ b/include/internal/cef_time.h @@ -69,6 +69,18 @@ CEF_EXPORT int cef_time_from_timet(time_t time, cef_time_t* cef_time); CEF_EXPORT int cef_time_to_doublet(const cef_time_t* cef_time, double* time); CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time); +/// +// Retrieve the current system time. +// +CEF_EXPORT int cef_time_now(cef_time_t* cef_time); + +/// +// Retrieve the delta in milliseconds between two time values. +// +CEF_EXPORT int cef_time_delta(const cef_time_t* cef_time1, + const cef_time_t* cef_time2, + long long* delta); + #ifdef __cplusplus } #endif diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 4b6a3d876..0a28c962b 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -494,6 +494,18 @@ class CefTime : public CefStructBase { cef_time_to_doublet(this, &time); return time; } + + // Set this object to now. + void Now() { + cef_time_now(this); + } + + // Return the delta between this object and |other| in milliseconds. + int64 Delta(const CefTime& other) { + int64 delta = 0; + cef_time_delta(this, &other, &delta); + return delta; + } }; diff --git a/libcef/common/time_impl.cc b/libcef/common/time_impl.cc index 1037915a2..68100b0b3 100644 --- a/libcef/common/time_impl.cc +++ b/libcef/common/time_impl.cc @@ -67,3 +67,27 @@ CEF_EXPORT int cef_time_from_doublet(double time, cef_time_t* cef_time) { cef_time_from_basetime(base_time, *cef_time); return 1; } + +CEF_EXPORT int cef_time_now(cef_time_t* cef_time) { + if (!cef_time) + return 0; + + base::Time base_time = base::Time::Now(); + cef_time_from_basetime(base_time, *cef_time); + return 1; +} + +CEF_EXPORT int cef_time_delta(const cef_time_t* cef_time1, + const cef_time_t* cef_time2, + long long* delta) { + if (!cef_time1 || !cef_time2 || !delta) + return 0; + + base::Time base_time1, base_time2; + cef_time_to_basetime(*cef_time1, base_time1); + cef_time_to_basetime(*cef_time2, base_time2); + + base::TimeDelta time_delta = base_time2 - base_time1; + *delta = time_delta.InMilliseconds(); + return 1; +} diff --git a/tests/cefclient/cefclient.rc b/tests/cefclient/cefclient.rc index dc2b95c76..699cef171 100644 --- a/tests/cefclient/cefclient.rc +++ b/tests/cefclient/cefclient.rc @@ -33,6 +33,7 @@ IDS_DIALOGS BINARY "res\\dialogs.html" IDS_LOGO BINARY "res\\logo.png" IDS_LOGOBALL BINARY "res\\logoball.png" IDS_LOCALSTORAGE BINARY "res\\localstorage.html" +IDS_PERFORMANCE BINARY "res\\performance.html" IDS_XMLHTTPREQUEST BINARY "res\\xmlhttprequest.html" IDS_DOMACCESS BINARY "res\\domaccess.html" @@ -69,6 +70,7 @@ BEGIN MENUITEM "Request", ID_TESTS_REQUEST MENUITEM "Scheme Handler", ID_TESTS_SCHEME_HANDLER MENUITEM "JavaScript Binding", ID_TESTS_BINDING + MENUITEM "Performance Tests", ID_TESTS_PERFORMANCE MENUITEM "Dialogs", ID_TESTS_DIALOGS MENUITEM "Plugin Info", ID_TESTS_PLUGIN_INFO MENUITEM "DOM Access", ID_TESTS_DOM_ACCESS diff --git a/tests/cefclient/cefclient_gtk.cpp b/tests/cefclient/cefclient_gtk.cpp index c77c038a0..acc9d0432 100644 --- a/tests/cefclient/cefclient_gtk.cpp +++ b/tests/cefclient/cefclient_gtk.cpp @@ -15,6 +15,7 @@ #include "cefclient/client_handler.h" #include "cefclient/dialog_test.h" #include "cefclient/dom_test.h" +#include "cefclient/performance_test.h" #include "cefclient/scheme_test.h" #include "cefclient/string_util.h" @@ -87,6 +88,14 @@ gboolean BindingActivated(GtkWidget* widget) { return FALSE; // Don't stop this message. } +// Callback for Debug > Performance... menu item. +gboolean PerformanceActivated(GtkWidget* widget) { + if (g_handler.get() && g_handler->GetBrowserId()) + performance_test::RunTest(g_handler->GetBrowser()); + + return FALSE; // Don't stop this message. +} + // Callback for Debug > Dialogs... menu item. gboolean DialogsActivated(GtkWidget* widget) { if (g_handler.get() && g_handler->GetBrowserId()) @@ -275,6 +284,8 @@ GtkWidget* CreateMenuBar() { G_CALLBACK(SchemeHandlerActivated)); AddMenuEntry(debug_menu, "JavaScript Binding", G_CALLBACK(BindingActivated)); + AddMenuEntry(debug_menu, "Performance Tests", + G_CALLBACK(PerformanceActivated)); AddMenuEntry(debug_menu, "Dialogs", G_CALLBACK(DialogsActivated)); AddMenuEntry(debug_menu, "Plugin Info", diff --git a/tests/cefclient/cefclient_mac.mm b/tests/cefclient/cefclient_mac.mm index 3d6e8cc45..564878a5e 100644 --- a/tests/cefclient/cefclient_mac.mm +++ b/tests/cefclient/cefclient_mac.mm @@ -15,6 +15,7 @@ #include "cefclient/client_handler.h" #include "cefclient/dialog_test.h" #include "cefclient/dom_test.h" +#include "cefclient/performance_test.h" #include "cefclient/resource_util.h" #include "cefclient/scheme_test.h" #include "cefclient/string_util.h" @@ -195,6 +196,7 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) { - (IBAction)testXMLHttpRequest:(id)sender; - (IBAction)testSchemeHandler:(id)sender; - (IBAction)testBinding:(id)sender; +- (IBAction)testPerformance:(id)sender; - (IBAction)testDialogs:(id)sender; - (IBAction)testPluginInfo:(id)sender; - (IBAction)testDOMAccess:(id)sender; @@ -245,6 +247,9 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) { [testMenu addItemWithTitle:@"JavaScript Binding" action:@selector(testBinding:) keyEquivalent:@""]; + [testMenu addItemWithTitle:@"Performance Tests" + action:@selector(testPerformance:) + keyEquivalent:@""]; [testMenu addItemWithTitle:@"Dialogs" action:@selector(testDialogs:) keyEquivalent:@""]; @@ -416,6 +421,11 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) { binding_test::RunTest(g_handler->GetBrowser()); } +- (IBAction)testPerformance:(id)sender { + if (g_handler.get() && g_handler->GetBrowserId()) + performance_test::RunTest(g_handler->GetBrowser()); +} + - (IBAction)testDialogs:(id)sender { if (g_handler.get() && g_handler->GetBrowserId()) dialog_test::RunTest(g_handler->GetBrowser()); diff --git a/tests/cefclient/cefclient_win.cpp b/tests/cefclient/cefclient_win.cpp index f86687798..5835ca148 100644 --- a/tests/cefclient/cefclient_win.cpp +++ b/tests/cefclient/cefclient_win.cpp @@ -17,6 +17,7 @@ #include "cefclient/client_handler.h" #include "cefclient/dialog_test.h" #include "cefclient/dom_test.h" +#include "cefclient/performance_test.h" #include "cefclient/resource.h" #include "cefclient/scheme_test.h" #include "cefclient/string_util.h" @@ -388,6 +389,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, if (browser.get()) binding_test::RunTest(browser); return 0; + case ID_TESTS_PERFORMANCE: // Run performance tests + if (browser.get()) + performance_test::RunTest(browser); + return 0; case ID_TESTS_DIALOGS: // Test JavaScript dialogs if (browser.get()) dialog_test::RunTest(browser); diff --git a/tests/cefclient/client_app_delegates.cpp b/tests/cefclient/client_app_delegates.cpp index cc6411914..23f16db40 100644 --- a/tests/cefclient/client_app_delegates.cpp +++ b/tests/cefclient/client_app_delegates.cpp @@ -5,6 +5,7 @@ #include "cefclient/client_app.h" #include "cefclient/client_renderer.h" #include "cefclient/dom_test.h" +#include "cefclient/performance_test.h" #include "cefclient/scheme_test.h" // static @@ -15,6 +16,7 @@ void ClientApp::CreateBrowserDelegates(BrowserDelegateSet& delegates) { void ClientApp::CreateRenderDelegates(RenderDelegateSet& delegates) { client_renderer::CreateRenderDelegates(delegates); dom_test::CreateRenderDelegates(delegates); + performance_test::CreateRenderDelegates(delegates); } // static diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index c1871f730..67679e871 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -20,6 +20,7 @@ #include "cefclient/client_switches.h" #include "cefclient/dialog_test.h" #include "cefclient/dom_test.h" +#include "cefclient/performance_test.h" #include "cefclient/resource_util.h" #include "cefclient/string_util.h" @@ -575,6 +576,9 @@ void ClientHandler::CreateProcessMessageDelegates( void ClientHandler::CreateRequestDelegates(RequestDelegateSet& delegates) { // Create the binding test delegates. binding_test::CreateRequestDelegates(delegates); + + // Create the performance test delegates. + performance_test::CreateRequestDelegates(delegates); } void ClientHandler::BuildTestMenu(CefRefPtr model) { diff --git a/tests/cefclient/performance_test.cpp b/tests/cefclient/performance_test.cpp new file mode 100644 index 000000000..e319fd417 --- /dev/null +++ b/tests/cefclient/performance_test.cpp @@ -0,0 +1,146 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "cefclient/performance_test.h" + +#include +#include + +#include "include/wrapper/cef_stream_resource_handler.h" +#include "cefclient/performance_test_setup.h" +#include "cefclient/resource_util.h" + +namespace performance_test { + +const size_t kDefaultIterations = 10000; + +namespace { + +const char kTestUrl[] = "http://tests/performance"; +const char kGetPerfTests[] = "GetPerfTests"; +const char kRunPerfTest[] = "RunPerfTest"; + +// Handle resource loading in the browser process. +class RequestDelegate: public ClientHandler::RequestDelegate { + public: + RequestDelegate() { + } + + // From ClientHandler::RequestDelegate. + virtual CefRefPtr GetResourceHandler( + CefRefPtr handler, + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request) OVERRIDE { + std::string url = request->GetURL(); + if (url == kTestUrl) { + // Show the test contents + CefRefPtr stream = + GetBinaryResourceReader("performance.html"); + ASSERT(stream.get()); + return new CefStreamResourceHandler("text/html", stream); + } + + return NULL; + } + + IMPLEMENT_REFCOUNTING(RequestDelegate); +}; + +class V8Handler : public CefV8Handler { + public: + V8Handler() { + } + + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) { + if (name == kRunPerfTest) { + if (arguments.size() == 1 && arguments[0]->IsString()) { + // Run the specified perf test. + bool found = false; + + std::string test = arguments[0]->GetStringValue(); + for (size_t i = 0; i < kPerfTestsCount; ++i) { + if (test == kPerfTests[i].name) { + // Execute the test. + int64 delta = kPerfTests[i].test(kPerfTests[i].iterations); + + retval = CefV8Value::CreateInt(delta); + found = true; + break; + } + } + + if (!found) { + std::string msg = "Unknown test: "; + msg.append(test); + exception = msg; + } + } else { + exception = "Invalid function parameters"; + } + } else if (name == kGetPerfTests) { + // Retrieve the list of perf tests. + retval = CefV8Value::CreateArray(kPerfTestsCount); + for (size_t i = 0; i < kPerfTestsCount; ++i) { + CefRefPtr val = CefV8Value::CreateArray(2); + val->SetValue(0, CefV8Value::CreateString(kPerfTests[i].name)); + val->SetValue(1, CefV8Value::CreateUInt(kPerfTests[i].iterations)); + retval->SetValue(i, val); + } + } + + return true; + } + + private: + IMPLEMENT_REFCOUNTING(V8Handler); +}; + +// Handle bindings in the render process. +class RenderDelegate : public ClientApp::RenderDelegate { + public: + RenderDelegate() { + } + + virtual void OnContextCreated(CefRefPtr app, + CefRefPtr browser, + CefRefPtr frame, + CefRefPtr context) OVERRIDE { + CefRefPtr object = context->GetGlobal(); + + CefRefPtr handler = new V8Handler(); + + // Bind test functions. + object->SetValue(kGetPerfTests, + CefV8Value::CreateFunction(kGetPerfTests, handler), + V8_PROPERTY_ATTRIBUTE_READONLY); + object->SetValue(kRunPerfTest, + CefV8Value::CreateFunction(kRunPerfTest, handler), + V8_PROPERTY_ATTRIBUTE_READONLY); + } + + private: + IMPLEMENT_REFCOUNTING(RenderDelegate); +}; + +} // namespace + +void CreateRequestDelegates(ClientHandler::RequestDelegateSet& delegates) { + delegates.insert(new RequestDelegate); +} + +void CreateRenderDelegates(ClientApp::RenderDelegateSet& delegates) { + delegates.insert(new RenderDelegate); +} + +void RunTest(CefRefPtr browser) { + // Load the test URL. + browser->GetMainFrame()->LoadURL(kTestUrl); +} + +} // namespace performance_test diff --git a/tests/cefclient/performance_test.h b/tests/cefclient/performance_test.h new file mode 100644 index 000000000..7b1162160 --- /dev/null +++ b/tests/cefclient/performance_test.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_H_ +#define CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_H_ +#pragma once + +#include "cefclient/client_app.h" +#include "cefclient/client_handler.h" + +namespace performance_test { + +// Request delegate creation. Called from ClientHandler. +void CreateRequestDelegates(ClientHandler::RequestDelegateSet& delegates); + +// Render delegate creation. Called from client_app_delegates.cpp. +void CreateRenderDelegates(ClientApp::RenderDelegateSet& delegates); + +// Run the test. +void RunTest(CefRefPtr browser); + +} // namespace performance_test + +#endif // CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_H_ diff --git a/tests/cefclient/performance_test_setup.h b/tests/cefclient/performance_test_setup.h new file mode 100644 index 000000000..a4f2647ef --- /dev/null +++ b/tests/cefclient/performance_test_setup.h @@ -0,0 +1,99 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#ifndef CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_SETUP_H_ +#define CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_SETUP_H_ +#pragma once + +#include "cefclient/util.h" + +namespace performance_test { + +// Default number of iterations. +extern const size_t kDefaultIterations; + +// Test name. +#define PERF_TEST_NAME(name) PerfTest##name + +// Entry in test array. +#define PERF_TEST_ENTRY_EX(name, iterations) \ + { #name, PERF_TEST_NAME(name), iterations } +#define PERF_TEST_ENTRY(name) PERF_TEST_ENTRY_EX(name, kDefaultIterations) + +// Test function declaration. +#define PERF_TEST_RESULT int64 +#define PERF_TEST_PARAM_ITERATIONS iterations +#define PERF_TEST_PARAMS size_t PERF_TEST_PARAM_ITERATIONS +#define PERF_TEST_FUNC(name) \ + PERF_TEST_RESULT PERF_TEST_NAME(name)(PERF_TEST_PARAMS) + +// Typedef for test pointers. +typedef PERF_TEST_RESULT(PerfTest(PERF_TEST_PARAMS)); + +class CefTimer { + public: + CefTimer() : running_(false) { + } + + bool IsRunning() { return running_; } + + void Start() { + ASSERT(!running_); + running_ = true; + start_.Now(); + } + + void Stop() { + stop_.Now(); + ASSERT(running_); + running_ = false; + } + + int64 Delta() { + ASSERT(!running_); + return start_.Delta(stop_); + } + + private: + bool running_; + CefTime start_; + CefTime stop_; +}; + +// Peform test iterations using a user-provided timing result variable. +#define PERF_ITERATIONS_START_EX() \ + { \ + CefTimer _timer; \ + _timer.Start(); \ + for (size_t _i = 0; _i < PERF_TEST_PARAM_ITERATIONS; ++_i) { + +#define PERF_ITERATIONS_END_EX(result) \ + } \ + _timer.Stop(); \ + result = _timer.Delta(); \ + } + +// Perform test iterations and return the timing result. +#define PERF_ITERATIONS_START() \ + int64 _result = 0; \ + PERF_ITERATIONS_START_EX() + +#define PERF_ITERATIONS_END() \ + PERF_ITERATIONS_END_EX(_result) \ + return _result; + +// Perf test entry structure. +struct PerfTestEntry { + const char* name; + PerfTest* test; + size_t iterations; +}; + +// Array of perf tests. +extern const PerfTestEntry kPerfTests[]; +extern const size_t kPerfTestsCount; + +} // namespace performance_test + +#endif // CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_H_ diff --git a/tests/cefclient/performance_test_tests.cpp b/tests/cefclient/performance_test_tests.cpp new file mode 100644 index 000000000..389a126a2 --- /dev/null +++ b/tests/cefclient/performance_test_tests.cpp @@ -0,0 +1,328 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "cefclient/performance_test.h" +#include "cefclient/performance_test_setup.h" +#include "include/cef_v8.h" + +namespace performance_test { + +namespace { + +// Test function implementations. + +PERF_TEST_FUNC(V8NullCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateNull(); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8BoolCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateBool(true); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8IntCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateInt(-5); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8UIntCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateUInt(10); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8DoubleCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateDouble(12.432); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8DateCreate) { + static cef_time_t time = {2012, 1, 0, 1}; + + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateDate(time); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8StringCreate) { + CefString str = "test string"; + + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateString(str); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ArrayCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateArray(1); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ArraySetValue) { + CefRefPtr val = CefV8Value::CreateBool(true); + CefRefPtr array = CefV8Value::CreateArray(1); + array->SetValue(0, val); + + PERF_ITERATIONS_START() + array->SetValue(0, val); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ArrayGetValue) { + CefRefPtr val = CefV8Value::CreateBool(true); + CefRefPtr array = CefV8Value::CreateArray(1); + array->SetValue(0, val); + + PERF_ITERATIONS_START() + CefRefPtr ret = array->GetValue(0); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8FunctionCreate) { + class Handler : public CefV8Handler { + public: + Handler() {} + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE { return false; } + IMPLEMENT_REFCOUNTING(Handler); + }; + + CefString name = "name"; + CefRefPtr handler = new Handler(); + + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateFunction(name, handler); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8FunctionExecute) { + class Handler : public CefV8Handler { + public: + Handler() {} + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE { return true; } + IMPLEMENT_REFCOUNTING(Handler); + }; + + CefString name = "name"; + CefRefPtr handler = new Handler(); + CefRefPtr func = CefV8Value::CreateFunction(name, handler); + CefRefPtr obj = CefV8Context::GetCurrentContext()->GetGlobal(); + CefV8ValueList args; + + PERF_ITERATIONS_START() + func->ExecuteFunction(obj, args); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8FunctionExecuteWithContext) { + class Handler : public CefV8Handler { + public: + Handler() {} + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE { return true; } + IMPLEMENT_REFCOUNTING(Handler); + }; + + CefString name = "name"; + CefRefPtr handler = new Handler(); + CefRefPtr func = CefV8Value::CreateFunction(name, handler); + CefRefPtr context = CefV8Context::GetCurrentContext(); + CefRefPtr obj = context->GetGlobal(); + CefV8ValueList args; + + PERF_ITERATIONS_START() + func->ExecuteFunctionWithContext(context, obj, args); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ObjectCreate) { + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateObject(NULL); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ObjectCreateWithAccessor) { + class Accessor : public CefV8Accessor { + public: + Accessor() {} + virtual bool Get(const CefString& name, + const CefRefPtr object, + CefRefPtr& retval, + CefString& exception) OVERRIDE { + return true; + } + virtual bool Set(const CefString& name, + const CefRefPtr object, + const CefRefPtr value, + CefString& exception) OVERRIDE { + return true; + } + IMPLEMENT_REFCOUNTING(Accessor); + }; + + CefRefPtr accessor = new Accessor(); + + PERF_ITERATIONS_START() + CefRefPtr value = CefV8Value::CreateObject(accessor); + PERF_ITERATIONS_END() +} + + +PERF_TEST_FUNC(V8ObjectSetValue) { + CefString name = "name"; + CefRefPtr val = CefV8Value::CreateBool(true); + CefRefPtr obj = CefV8Value::CreateObject(NULL); + obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE); + + PERF_ITERATIONS_START() + obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ObjectGetValue) { + CefString name = "name"; + CefRefPtr val = CefV8Value::CreateBool(true); + CefRefPtr obj = CefV8Value::CreateObject(NULL); + obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE); + + PERF_ITERATIONS_START() + CefRefPtr ret = obj->GetValue(name); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ObjectSetValueWithAccessor) { + class Accessor : public CefV8Accessor { + public: + Accessor() {} + virtual bool Get(const CefString& name, + const CefRefPtr object, + CefRefPtr& retval, + CefString& exception) OVERRIDE { + return true; + } + virtual bool Set(const CefString& name, + const CefRefPtr object, + const CefRefPtr value, + CefString& exception) OVERRIDE { + val_ = value; + return true; + } + CefRefPtr val_; + IMPLEMENT_REFCOUNTING(Accessor); + }; + + CefRefPtr accessor = new Accessor(); + + CefString name = "name"; + CefRefPtr val = CefV8Value::CreateBool(true); + CefRefPtr obj = CefV8Value::CreateObject(accessor); + obj->SetValue(name, V8_ACCESS_CONTROL_DEFAULT, V8_PROPERTY_ATTRIBUTE_NONE); + obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE); + + PERF_ITERATIONS_START() + obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ObjectGetValueWithAccessor) { + class Accessor : public CefV8Accessor { + public: + Accessor() : val_(CefV8Value::CreateBool(true)) {} + virtual bool Get(const CefString& name, + const CefRefPtr object, + CefRefPtr& retval, + CefString& exception) OVERRIDE { + retval = val_; + return true; + } + virtual bool Set(const CefString& name, + const CefRefPtr object, + const CefRefPtr value, + CefString& exception) OVERRIDE { + return true; + } + CefRefPtr val_; + IMPLEMENT_REFCOUNTING(Accessor); + }; + + CefRefPtr accessor = new Accessor(); + + CefString name = "name"; + CefRefPtr val = CefV8Value::CreateBool(true); + CefRefPtr obj = CefV8Value::CreateObject(accessor); + obj->SetValue(name, V8_ACCESS_CONTROL_DEFAULT, V8_PROPERTY_ATTRIBUTE_NONE); + obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE); + + PERF_ITERATIONS_START() + CefRefPtr ret = obj->GetValue(name); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ContextEnterExit) { + CefRefPtr context = CefV8Context::GetCurrentContext(); + + PERF_ITERATIONS_START() + context->Enter(); + context->Exit(); + PERF_ITERATIONS_END() +} + +PERF_TEST_FUNC(V8ContextEval) { + CefRefPtr context = CefV8Context::GetCurrentContext(); + CefString jsCode = "var i = 0;"; + CefRefPtr retval; + CefRefPtr exception; + + PERF_ITERATIONS_START() + context->Eval(jsCode, retval, exception); + PERF_ITERATIONS_END() +} + +} // namespace + + +// Test function entries. + +const PerfTestEntry kPerfTests[] = { + PERF_TEST_ENTRY(V8NullCreate), + PERF_TEST_ENTRY(V8BoolCreate), + PERF_TEST_ENTRY(V8IntCreate), + PERF_TEST_ENTRY(V8UIntCreate), + PERF_TEST_ENTRY(V8DoubleCreate), + PERF_TEST_ENTRY(V8DateCreate), + PERF_TEST_ENTRY(V8StringCreate), + PERF_TEST_ENTRY(V8ArrayCreate), + PERF_TEST_ENTRY(V8ArraySetValue), + PERF_TEST_ENTRY(V8ArrayGetValue), + PERF_TEST_ENTRY(V8FunctionCreate), + PERF_TEST_ENTRY(V8FunctionExecute), + PERF_TEST_ENTRY(V8FunctionExecuteWithContext), + PERF_TEST_ENTRY(V8ObjectCreate), + PERF_TEST_ENTRY(V8ObjectCreateWithAccessor), + PERF_TEST_ENTRY(V8ObjectSetValue), + PERF_TEST_ENTRY(V8ObjectGetValue), + PERF_TEST_ENTRY(V8ObjectSetValueWithAccessor), + PERF_TEST_ENTRY(V8ObjectGetValueWithAccessor), + PERF_TEST_ENTRY(V8ContextEnterExit), + PERF_TEST_ENTRY(V8ContextEval), +}; + +const size_t kPerfTestsCount = (sizeof(kPerfTests) / sizeof(kPerfTests[0])); + +} // namespace performance_test diff --git a/tests/cefclient/res/performance.html b/tests/cefclient/res/performance.html new file mode 100644 index 000000000..df7f0a5d7 --- /dev/null +++ b/tests/cefclient/res/performance.html @@ -0,0 +1,293 @@ + + + + Performance Tests + + + +

Performance Tests

+ Filter: +
+ +
+ + + + + + + + + + + + + +
NameIterations per RunAvg (ms)Min (ms)Max (ms)StdDev (ms)Runs (ms)
+
+ +
+ + Result 1: +
Result 2: +
+ +
+ + + + + + + + + + +
NameResult 1 Avg (ms)Result 2 Avg (ms)% Diff
+
+ + + + + diff --git a/tests/cefclient/resource.h b/tests/cefclient/resource.h index 05ecd6b94..30d8ab7bc 100644 --- a/tests/cefclient/resource.h +++ b/tests/cefclient/resource.h @@ -46,6 +46,7 @@ #define ID_TESTS_ZOOM_RESET 32779 #define ID_TESTS_BEGIN_TRACING 32780 #define ID_TESTS_END_TRACING 32781 +#define ID_TESTS_PERFORMANCE 32782 #define IDC_STATIC -1 #define IDS_BINDING 1000 #define IDS_DIALOGS 1001 @@ -54,6 +55,7 @@ #define IDS_LOCALSTORAGE 1004 #define IDS_XMLHTTPREQUEST 1005 #define IDS_DOMACCESS 1006 +#define IDS_PERFORMANCE 1007 // Avoid files associated with MacOS #define _X86_ diff --git a/tests/cefclient/resource_util_win.cpp b/tests/cefclient/resource_util_win.cpp index 8482ac954..390484007 100644 --- a/tests/cefclient/resource_util_win.cpp +++ b/tests/cefclient/resource_util_win.cpp @@ -49,6 +49,7 @@ CefRefPtr GetBinaryResourceReader(const char* resource_name) { {"dialogs.html", IDS_DIALOGS}, {"domaccess.html", IDS_DOMACCESS}, {"localstorage.html", IDS_LOCALSTORAGE}, + {"performance.html", IDS_PERFORMANCE}, {"xmlhttprequest.html", IDS_XMLHTTPREQUEST}, };