Add performance tests for CEF V8 methods (issue #484).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@879 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2012-10-26 20:39:24 +00:00
parent a9a7b8940d
commit ce76bfc1e1
21 changed files with 955 additions and 171 deletions

View File

@ -93,10 +93,14 @@
'tests/cefclient/download_handler.h',
'tests/cefclient/extension_test.cpp',
'tests/cefclient/extension_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/domaccess.html',
'tests/cefclient/res/extensionperf.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',
@ -149,10 +153,10 @@
'tests/cefclient/mac/English.lproj/MainMenu.xib',
'tests/cefclient/mac/Info.plist',
'tests/cefclient/res/domaccess.html',
'tests/cefclient/res/extensionperf.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/logoball.png',
'tests/cefclient/res/performance.html',
'tests/cefclient/res/osrtest.html',
'tests/cefclient/res/transparency.html',
'tests/cefclient/res/xmlhttprequest.html',
@ -164,9 +168,9 @@
],
'cefclient_bundle_resources_linux': [
'tests/cefclient/res/domaccess.html',
'tests/cefclient/res/extensionperf.html',
'tests/cefclient/res/localstorage.html',
'tests/cefclient/res/logo.png',
'tests/cefclient/res/performance.html',
'tests/cefclient/res/xmlhttprequest.html',
],
},

View File

@ -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

View File

@ -499,6 +499,18 @@ class CefTime : public CefStructBase<CefTimeTraits> {
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;
}
};

View File

@ -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;
}

View File

@ -37,7 +37,7 @@ IDS_XMLHTTPREQUEST BINARY "res\\xmlhttprequest.html"
IDS_DOMACCESS BINARY "res\\domaccess.html"
IDS_MODALMAIN BINARY "res\\modalmain.html"
IDS_MODALDIALOG BINARY "res\\modaldialog.html"
IDS_EXTENSIONPERF BINARY "res\\extensionperf.html"
IDS_PERFORMANCE BINARY "res\\performance.html"
IDS_TRANSPARENCY BINARY "res\\transparency.html"
/////////////////////////////////////////////////////////////////////////////
@ -75,9 +75,9 @@ BEGIN
MENUITEM "Get Text", ID_TESTS_GETTEXT
MENUITEM "JavaScript Binding Handler", ID_TESTS_JAVASCRIPT_BINDING
MENUITEM "JavaScript Extension Handler",ID_TESTS_JAVASCRIPT_EXTENSION
MENUITEM "JavaScript Extension Performance",ID_TESTS_JAVASCRIPT_PERFORMANCE
MENUITEM "JavaScript Execute", ID_TESTS_JAVASCRIPT_EXECUTE
MENUITEM "JavaScript Invoke", ID_TESTS_JAVASCRIPT_INVOKE
MENUITEM "Performance Tests", ID_TESTS_PERFORMANCE
MENUITEM "Plugin", ID_TESTS_PLUGIN
MENUITEM "Plugin Info", ID_TESTS_PLUGIN_INFO
MENUITEM "Popup Window", ID_TESTS_POPUP

View File

@ -14,6 +14,7 @@
#include "cefclient/binding_test.h"
#include "cefclient/client_handler.h"
#include "cefclient/extension_test.h"
#include "cefclient/performance_test.h"
#include "cefclient/scheme_test.h"
#include "cefclient/string_util.h"
@ -70,6 +71,14 @@ gboolean JSExecuteActivated(GtkWidget* widget) {
return FALSE; // Don't stop this message.
}
// Callback for Debug > Performance Tests... menu item.
gboolean PerformanceActivated(GtkWidget* widget) {
if (g_handler.get() && g_handler->GetBrowserHwnd())
performance_test::RunTest(g_handler->GetBrowser());
return FALSE; // Don't stop this message.
}
// Callback for Debug > Request... menu item.
gboolean RequestActivated(GtkWidget* widget) {
if (g_handler.get() && g_handler->GetBrowserHwnd())
@ -280,6 +289,8 @@ GtkWidget* CreateMenuBar() {
G_CALLBACK(JSExtensionActivated));
AddMenuEntry(debug_menu, "JS Execute",
G_CALLBACK(JSExecuteActivated));
AddMenuEntry(debug_menu, "Performance Tests",
G_CALLBACK(PerformanceActivated));
AddMenuEntry(debug_menu, "Request",
G_CALLBACK(RequestActivated));
AddMenuEntry(debug_menu, "Local Storage",

View File

@ -15,6 +15,7 @@
#include "cefclient/client_handler.h"
#include "cefclient/extension_test.h"
#include "cefclient/osrtest_mac.h"
#include "cefclient/performance_test.h"
#include "cefclient/resource_util.h"
#include "cefclient/scheme_test.h"
#include "cefclient/string_util.h"
@ -192,9 +193,9 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
- (IBAction)testGetText:(id)sender;
- (IBAction)testJSBinding:(id)sender;
- (IBAction)testJSExtension:(id)sender;
- (IBAction)testJSExtensionPerf:(id)sender;
- (IBAction)testJSExecute:(id)sender;
- (IBAction)testJSInvoke:(id)sender;
- (IBAction)testPerformance:(id)sender;
- (IBAction)testRequest:(id)sender;
- (IBAction)testLocalStorage:(id)sender;
- (IBAction)testXMLHttpRequest:(id)sender;
@ -245,15 +246,15 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
[testMenu addItemWithTitle:@"JavaScript Extension Handler"
action:@selector(testJSExtension:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"JavaScript Extension Performance"
action:@selector(testJSExtensionPerf:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"JavaScript Execute"
action:@selector(testJSExecute:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"JavaScript Invoke"
action:@selector(testJSInvoke:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Performance Tests"
action:@selector(testPerformance:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Popup Window"
action:@selector(testPopupWindow:)
keyEquivalent:@""];
@ -425,11 +426,6 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
RunExtensionTest(g_handler->GetBrowser());
}
- (IBAction)testJSExtensionPerf:(id)sender {
if (g_handler.get() && g_handler->GetBrowserHwnd())
RunExtensionPerfTest(g_handler->GetBrowser());
}
- (IBAction)testJSExecute:(id)sender {
if (g_handler.get() && g_handler->GetBrowserHwnd())
RunJavaScriptExecuteTest(g_handler->GetBrowser());
@ -440,6 +436,11 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
RunJavaScriptInvokeTest(g_handler->GetBrowser());
}
- (IBAction)testPerformance:(id)sender {
if (g_handler.get() && g_handler->GetBrowserHwnd())
performance_test::RunTest(g_handler->GetBrowser());
}
- (IBAction)testRequest:(id)sender {
if (g_handler.get() && g_handler->GetBrowserHwnd())
RunRequestTest(g_handler->GetBrowser());

View File

@ -17,6 +17,7 @@
#include "cefclient/client_handler.h"
#include "cefclient/extension_test.h"
#include "cefclient/osrplugin_test.h"
#include "cefclient/performance_test.h"
#include "cefclient/plugin_test.h"
#include "cefclient/resource.h"
#include "cefclient/scheme_test.h"
@ -448,10 +449,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
if (browser.get())
RunExtensionTest(browser);
return 0;
case ID_TESTS_JAVASCRIPT_PERFORMANCE: // Test the V8 performance
if (browser.get())
RunExtensionPerfTest(browser);
return 0;
case ID_TESTS_JAVASCRIPT_EXECUTE: // Test execution of javascript
if (browser.get())
RunJavaScriptExecuteTest(browser);
@ -460,6 +457,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
if (browser.get())
RunJavaScriptInvokeTest(browser);
return 0;
case ID_TESTS_PERFORMANCE: // Run performance tests
if (browser.get())
performance_test::RunTest(browser);
return 0;
case ID_TESTS_PLUGIN: // Test the custom plugin
if (browser.get())
RunPluginTest(browser);

View File

@ -13,6 +13,7 @@
#include "cefclient/cefclient.h"
#include "cefclient/cefclient_switches.h"
#include "cefclient/download_handler.h"
#include "cefclient/performance_test.h"
#include "cefclient/string_util.h"
ClientHandler::ClientHandler()
@ -262,8 +263,14 @@ void ClientHandler::OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefV8Context> context) {
REQUIRE_UI_THREAD();
CefRefPtr<CefV8Value> object = context->GetGlobal();
// Add the V8 bindings.
InitBindingTest(browser, frame, context->GetGlobal());
InitBindingTest(browser, frame, object);
std::string url = frame->GetURL();
if (url == performance_test::kTestUrl)
performance_test::InitTest(browser, frame, object);
}
bool ClientHandler::OnDragStart(CefRefPtr<CefBrowser> browser,

View File

@ -7,6 +7,7 @@
#include "cefclient/client_handler.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "cefclient/performance_test.h"
#include "cefclient/resource_util.h"
#include "cefclient/string_util.h"
@ -61,6 +62,10 @@ bool ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
resourceStream = GetBinaryResourceReader("domaccess.html");
response->SetMimeType("text/html");
response->SetStatus(200);
} else if (url == performance_test::kTestUrl) {
resourceStream = GetBinaryResourceReader("performance.html");
response->SetMimeType("text/html");
response->SetStatus(200);
}
return false;

View File

@ -8,6 +8,7 @@
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "cefclient/cefclient.h"
#include "cefclient/performance_test.h"
#include "cefclient/resource_util.h"
#include "cefclient/string_util.h"
@ -75,6 +76,10 @@ bool ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
resourceStream = GetBinaryResourceReader("domaccess.html");
response->SetMimeType("text/html");
response->SetStatus(200);
} else if (url == performance_test::kTestUrl) {
resourceStream = GetBinaryResourceReader("performance.html");
response->SetMimeType("text/html");
response->SetStatus(200);
}
return false;

View File

@ -6,6 +6,7 @@
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "cefclient/performance_test.h"
#include "cefclient/resource.h"
#include "cefclient/resource_util.h"
#include "cefclient/string_util.h"
@ -115,6 +116,10 @@ bool ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
html.size());
response->SetMimeType("text/html");
response->SetStatus(200);
} else if (url == performance_test::kTestUrl) {
resourceStream = GetBinaryResourceReader(IDS_PERFORMANCE);
response->SetMimeType("text/html");
response->SetStatus(200);
}
return false;

View File

@ -23,10 +23,7 @@ class ClientV8ExtensionHandler : public CefV8Handler {
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) {
if (name == "Dummy") {
// Used for performance testing.
return true;
} else if (name == "SetTestParam") {
if (name == "SetTestParam") {
// Handle the SetTestParam native function by saving the string argument
// into the local member.
if (arguments.size() != 1 || !arguments[0]->IsString())
@ -89,10 +86,6 @@ void InitExtensionTest() {
" native function GetTestObject();"
" return GetTestObject();"
" };"
" cef.test.dummy = function() {"
" native function Dummy();"
" return Dummy();"
" };"
"})();";
CefRegisterExtension("v8/test", code, new ClientV8ExtensionHandler());
}
@ -114,13 +107,3 @@ void RunExtensionTest(CefRefPtr<CefBrowser> browser) {
"</pre></body></html>";
browser->GetMainFrame()->LoadString(html, "about:blank");
}
void RunExtensionPerfTest(CefRefPtr<CefBrowser> browser) {
CefRefPtr<CefStreamReader> resourceStream;
#if defined(OS_WIN)
resourceStream = GetBinaryResourceReader(IDS_EXTENSIONPERF);
#elif defined(OS_MACOSX)
resourceStream = GetBinaryResourceReader("extensionperf.html");
#endif
browser->GetMainFrame()->LoadStream(resourceStream, "about:blank");
}

View File

@ -15,6 +15,5 @@ void InitExtensionTest();
// Run the test.
void RunExtensionTest(CefRefPtr<CefBrowser> browser);
void RunExtensionPerfTest(CefRefPtr<CefBrowser> browser);
#endif // CEF_TESTS_CEFCLIENT_EXTENSION_TEST_H_

View File

@ -0,0 +1,98 @@
// 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/cef_v8.h"
#include <algorithm>
#include <string>
#include "cefclient/performance_test_setup.h"
#include "cefclient/resource_util.h"
namespace performance_test {
const size_t kDefaultIterations = 10000;
const char kTestUrl[] = "http://tests/performance";
namespace {
const char kGetPerfTests[] = "GetPerfTests";
const char kRunPerfTest[] = "RunPerfTest";
class V8Handler : public CefV8Handler {
public:
V8Handler() {
}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& 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<CefV8Value> 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);
};
} // namespace
void InitTest(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Value> object) {
CefRefPtr<CefV8Handler> 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);
}
void RunTest(CefRefPtr<CefBrowser> browser) {
// Load the test URL.
browser->GetMainFrame()->LoadURL(kTestUrl);
}
} // namespace performance_test

View File

@ -0,0 +1,28 @@
// 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 "include/cef_base.h"
class CefBrowser;
class CefFrame;
class CefV8Value;
namespace performance_test {
extern const char kTestUrl[];
void InitTest(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Value> object);
// Run the test.
void RunTest(CefRefPtr<CefBrowser> browser);
} // namespace performance_test
#endif // CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_H_

View File

@ -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_

View File

@ -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<CefV8Value> value = CefV8Value::CreateNull();
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8BoolCreate) {
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> value = CefV8Value::CreateBool(true);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8IntCreate) {
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> value = CefV8Value::CreateInt(-5);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8UIntCreate) {
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> value = CefV8Value::CreateUInt(10);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8DoubleCreate) {
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> 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<CefV8Value> value = CefV8Value::CreateDate(time);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8StringCreate) {
CefString str = "test string";
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> value = CefV8Value::CreateString(str);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ArrayCreate) {
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> value = CefV8Value::CreateArray(1);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ArraySetValue) {
CefRefPtr<CefV8Value> val = CefV8Value::CreateBool(true);
CefRefPtr<CefV8Value> array = CefV8Value::CreateArray(1);
array->SetValue(0, val);
PERF_ITERATIONS_START()
array->SetValue(0, val);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ArrayGetValue) {
CefRefPtr<CefV8Value> val = CefV8Value::CreateBool(true);
CefRefPtr<CefV8Value> array = CefV8Value::CreateArray(1);
array->SetValue(0, val);
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> ret = array->GetValue(0);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8FunctionCreate) {
class Handler : public CefV8Handler {
public:
Handler() {}
virtual bool Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE { return false; }
IMPLEMENT_REFCOUNTING(Handler);
};
CefString name = "name";
CefRefPtr<CefV8Handler> handler = new Handler();
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> 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<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE { return true; }
IMPLEMENT_REFCOUNTING(Handler);
};
CefString name = "name";
CefRefPtr<CefV8Handler> handler = new Handler();
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction(name, handler);
CefRefPtr<CefV8Value> 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<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE { return true; }
IMPLEMENT_REFCOUNTING(Handler);
};
CefString name = "name";
CefRefPtr<CefV8Handler> handler = new Handler();
CefRefPtr<CefV8Value> func = CefV8Value::CreateFunction(name, handler);
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
CefRefPtr<CefV8Value> obj = context->GetGlobal();
CefV8ValueList args;
PERF_ITERATIONS_START()
func->ExecuteFunctionWithContext(context, obj, args);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ObjectCreate) {
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> 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<CefV8Value> object,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
return true;
}
virtual bool Set(const CefString& name,
const CefRefPtr<CefV8Value> object,
const CefRefPtr<CefV8Value> value,
CefString& exception) OVERRIDE {
return true;
}
IMPLEMENT_REFCOUNTING(Accessor);
};
CefRefPtr<CefV8Accessor> accessor = new Accessor();
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> value = CefV8Value::CreateObject(accessor);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ObjectSetValue) {
CefString name = "name";
CefRefPtr<CefV8Value> val = CefV8Value::CreateBool(true);
CefRefPtr<CefV8Value> 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<CefV8Value> val = CefV8Value::CreateBool(true);
CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(NULL);
obj->SetValue(name, val, V8_PROPERTY_ATTRIBUTE_NONE);
PERF_ITERATIONS_START()
CefRefPtr<CefV8Value> 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<CefV8Value> object,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
return true;
}
virtual bool Set(const CefString& name,
const CefRefPtr<CefV8Value> object,
const CefRefPtr<CefV8Value> value,
CefString& exception) OVERRIDE {
val_ = value;
return true;
}
CefRefPtr<CefV8Value> val_;
IMPLEMENT_REFCOUNTING(Accessor);
};
CefRefPtr<CefV8Accessor> accessor = new Accessor();
CefString name = "name";
CefRefPtr<CefV8Value> val = CefV8Value::CreateBool(true);
CefRefPtr<CefV8Value> 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<CefV8Value> object,
CefRefPtr<CefV8Value>& retval,
CefString& exception) OVERRIDE {
retval = val_;
return true;
}
virtual bool Set(const CefString& name,
const CefRefPtr<CefV8Value> object,
const CefRefPtr<CefV8Value> value,
CefString& exception) OVERRIDE {
return true;
}
CefRefPtr<CefV8Value> val_;
IMPLEMENT_REFCOUNTING(Accessor);
};
CefRefPtr<CefV8Accessor> accessor = new Accessor();
CefString name = "name";
CefRefPtr<CefV8Value> val = CefV8Value::CreateBool(true);
CefRefPtr<CefV8Value> 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<CefV8Value> ret = obj->GetValue(name);
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ContextEnterExit) {
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
PERF_ITERATIONS_START()
context->Enter();
context->Exit();
PERF_ITERATIONS_END()
}
PERF_TEST_FUNC(V8ContextEval) {
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
CefString jsCode = "var i = 0;";
CefRefPtr<CefV8Value> retval;
CefRefPtr<CefV8Exception> 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

View File

@ -1,131 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>JavaScript Extension: Performance</title>
<style>
body { font-family: Tahoma, Serif; font-size: 9pt; }
</style>
</head>
<body>
<h1>JavaScript Extension: Performance</h1>
<div><span id="statusBox"></span> <progress id="progressBox" value="0" style="display:none"></progress></div>
<div style="padding-top:10px; padding-bottom:10px">
<table id="resultTable" border="1" cellspacing="1" cellpadding="4" width="100%">
<thead>
<tr>
<td>Name</td>
<td>Min</td>
<td>Avg</td>
<td>Max</td>
<td>Probes</td>
</tr>
</thead>
<!-- result rows here -->
</table>
</div>
<script type="text/javascript">
(function () {
var asyncExecution = true;
var testIterations = 100000;
var totalProbes = 10;
var probeDelay = 0;
var collectProbes = false;
function dummyCallTest() {
for (var i = 0; i < testIterations; i++) {
cef.test.dummy();
}
}
function execTestFunc(func) {
var begin = new Date();
func();
var end = new Date();
return (end - begin);
}
function execTest(test) {
function nextStep() {
if (asyncExecution) {
setTimeout(function () { execTest(test); }, probeDelay);
} else {
execTest(test);
}
}
function nextTest() {
appendResult(test);
// ...
}
updateStatus(test);
if (!test.warmedUp) {
execTestFunc(test.func);
test.warmedUp = true;
return nextStep();
}
if (test.probe >= test.totalProbes) {
test.avg = test.total / test.totalProbes;
return nextTest();
}
var elapsed = execTestFunc(test.func);
test.total += elapsed;
if (!test.min) test.min = elapsed;
else if (test.min > elapsed) test.min = elapsed;
if (!test.max) test.max = elapsed;
else if (test.max < elapsed) test.max = elapsed;
if (collectProbes) {
test.results.push(elapsed);
}
test.probe++;
return nextStep();
}
function updateStatus(test) {
var statusBox = document.getElementById("statusBox");
var progressBox = document.getElementById("progressBox");
if (test.probe >= test.totalProbes) {
statusBox.innerText = test.name + " completed.";
progressBox.style.display = 'none';
} else {
statusBox.innerText = test.name + " (" + test.probe + "/" + test.totalProbes + ")";
progressBox.value = (test.probe / test.totalProbes);
progressBox.style.display = 'inline';
}
}
function appendResult(test) {
var e = document.getElementById("resultTable");
e.insertAdjacentHTML("beforeEnd",
["<tr>",
"<td>", test.name, "</td>",
"<td>", test.min, "ms</td>",
"<td>", test.avg, "ms</td>",
"<td>", test.max, "ms</td>",
"<td>", test.results.join(", "), "</td>",
"<tr>"
].join("")
);
}
function runTest(name, func) {
var test = { name: name, func: func, warmedUp: false, total: 0, totalProbes: totalProbes, probe: 0, results: [] };
setTimeout(function () { execTest(test); }, 10);
}
runTest("dummyCall", dummyCallTest);
})();
</script>
</body>
</html>

View File

@ -0,0 +1,293 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Performance Tests</title>
<style>
body { font-family: Tahoma, Serif; font-size: 9pt; }
</style>
</head>
<body>
<h1>Performance Tests</h1>
<input type="button" value="Run Tests" onClick="run();" id="run"/> Filter: <input type="text" size="50" id="filters"/>
<div><span id="statusBox"></span> <progress id="progressBox" value="0" style="display:none"></progress></div>
<div style="padding-top:10px; padding-bottom:10px">
<table id="resultTable" border="1" cellspacing="1" cellpadding="4">
<thead>
<tr>
<td>Name</td>
<td>Iterations per Run</td>
<td>Avg (ms)</td>
<td>Min (ms)</td>
<td>Max (ms)</td>
<td>StdDev (ms)</td>
<td>Runs (ms)</td>
</tr>
</thead>
<!-- result rows here -->
</table>
</div>
<hr width="80%">
Result 1: <input type="text" size="100" id="result1"/>
<br/>Result 2: <input type="text" size="100" id="result2"/>
<br/><input type="button" value="Compare" onClick="compare();" id="compare"/>
<div style="padding-top:10px; padding-bottom:10px">
<table id="compareTable" border="1" cellspacing="1" cellpadding="4">
<thead>
<tr>
<td>Name</td>
<td>Result 1 Avg (ms)</td>
<td>Result 2 Avg (ms)</td>
<td>% Diff</td>
</tr>
</thead>
<!-- result rows here -->
</table>
</div>
<script type="text/javascript">
function run() {
var runElement = document.getElementById("run");
var filtersElement = document.getElementById("filters");
var compareElement = document.getElementById("compare");
var result1Element = document.getElementById("result1");
var result2Element = document.getElementById("result2");
// Number of runs for each test.
var testRuns = 10;
// Delay between test runs.
var runDelay = 0;
// Retrieve the list of all tests.
var allTests = window.GetPerfTests();
// Populated with the list of tests that will be run.
var tests = [];
var currentTest = 0;
var testList = filtersElement.value.trim();
if (testList.length > 0) {
// Include or exclude specific tests.
var included = [];
var excluded = [];
var testNames = testList.split(",");
// Identify included and excluded tests.
for (i = 0; i < testNames.length; ++i) {
var testName = testNames[i].trim();
if (testName[0] == '-') {
// Exclude the test.
excluded.push(testName.substr(1));
} else {
// Include the test.
included.push(testName);
}
}
if (included.length > 0) {
// Only use the included tests.
for (i = 0; i < allTests.length; ++i) {
var test = allTests[i];
var testName = test[0];
if (included.indexOf(testName) >= 0)
tests.push(test);
}
} else if (excluded.length > 0) {
// Use all tests except the excluded tests.
for (i = 0; i < allTests.length; ++i) {
var test = allTests[i];
var testName = test[0];
if (excluded.indexOf(testName) < 0)
tests.push(test);
}
}
} else {
// Run all tests.
tests = allTests;
}
function updateStatusComplete() {
var statusBox = document.getElementById("statusBox");
statusBox.innerText = 'All tests completed.';
runElement.disabled = false;
filtersElement.disabled = false;
result1Element.disabled = false;
result2Element.disabled = false;
compareElement.disabled = false;
}
function updateStatus(test) {
var statusBox = document.getElementById("statusBox");
var progressBox = document.getElementById("progressBox");
if (test.run >= test.totalRuns) {
statusBox.innerText = test.name + " completed.";
progressBox.style.display = 'none';
} else {
statusBox.innerText = test.name + " (" + test.run + "/" + test.totalRuns + ")";
progressBox.value = (test.run / test.totalRuns);
progressBox.style.display = 'inline';
}
}
function appendResult(test) {
var e = document.getElementById("resultTable");
// Calculate the average.
var avg = test.total / test.totalRuns;
// Calculate the standard deviation.
var sqsum = 0;
for (i = 0; i < test.results.length; ++i) {
var diff = test.results[i] - avg;
sqsum += diff * diff;
}
var stddev = Math.round(Math.sqrt(sqsum / test.totalRuns) * 100.0) / 100.0;
e.insertAdjacentHTML("beforeEnd", [
"<tr>",
"<td>", test.name, "</td>",
"<td>", test.iterations, "</td>",
"<td>", avg, "</td>",
"<td>", test.min, "</td>",
"<td>", test.max, "</td>",
"<td>", stddev, "</td>",
"<td>", test.results.join(", "), "</td>",
"<tr>"
].join(""));
if (result1Element.value.length > 0)
result1Element.value += ",";
result1Element.value += test.name + "=" + avg;
}
// Execute the test function.
function execTestFunc(name) {
return window.RunPerfTest(name);
}
// Schedule the next test.
function nextTest(test) {
appendResult(test);
currentTest++;
runTest();
}
// Schedule the next step for the current test.
function nextTestStep(test) {
setTimeout(function () { execTest(test); }, runDelay);
}
// Perform the next step for the current test.
function execTest(test) {
updateStatus(test);
if (!test.warmedUp) {
execTestFunc(test.name);
test.warmedUp = true;
return nextTestStep(test);
}
if (test.run >= test.totalRuns)
return nextTest(test);
var elapsed = execTestFunc(test.name);
test.results.push(elapsed);
test.total += elapsed;
if (!test.min) test.min = elapsed;
else if (test.min > elapsed) test.min = elapsed;
if (!test.max) test.max = elapsed;
else if (test.max < elapsed) test.max = elapsed;
test.run++;
return nextTestStep(test);
}
function runTest() {
if (currentTest == tests.length) {
updateStatusComplete();
return;
}
var test = {
name: tests[currentTest][0],
iterations: tests[currentTest][1],
warmedUp: false,
total: 0,
totalRuns: testRuns,
run: 0,
results: []
};
setTimeout(function () { execTest(test); }, runDelay);
}
// Schedule the first test.
if (tests.length > 0) {
runElement.disabled = true;
filtersElement.disabled = true;
result1Element.value = "";
result1Element.disabled = true;
result2Element.disabled = true;
compareElement.disabled = true;
runTest();
}
}
function compare() {
var result1 = document.getElementById("result1").value.trim();
var result2 = document.getElementById("result2").value.trim();
if (result1.length == 0 || result2.length == 0)
return;
var r1values = result1.split(",");
var r2values = result2.split(",");
for (i = 0; i < r1values.length; ++i) {
var r1parts = r1values[i].split("=");
var r1name = r1parts[0].trim();
var r1val = r1parts[1].trim();
for (x = 0; x < r2values.length; ++x) {
var r2parts = r2values[x].split("=");
var r2name = r2parts[0].trim();
var r2val = r2parts[1].trim();
if (r2name == r1name) {
appendResult(r1name, r1val, r2val);
// Remove the matching index.
r2values.splice(x, 1);
break;
}
}
}
function appendResult(name, r1val, r2val) {
var e = document.getElementById("compareTable");
// Calculate the percent difference.
var diff = Math.round(((r2val - r1val) / r1val) * 10000.0) / 100.0;
e.insertAdjacentHTML("beforeEnd", [
"<tr>",
"<td>", name, "</td>",
"<td>", r1val, "</td>",
"<td>", r2val, "</td>",
"<td>", diff, "</td>",
"<tr>"
].join(""));
}
}
</script>
</body>
</html>

View File

@ -51,7 +51,7 @@
#define ID_TESTS_DRAGDROP 32792
#define ID_TESTS_OSRAPP 32793
#define ID_TESTS_MODALDIALOG 32794
#define ID_TESTS_JAVASCRIPT_PERFORMANCE 32795
#define ID_TESTS_PERFORMANCE 32795
#define ID_TESTS_TRANSPARENT_POPUP 32796
#define ID_TESTS_TRANSPARENT_OSRAPP 32797
#define ID_TESTS_JAVASCRIPT_INVOKE 32798
@ -68,7 +68,7 @@
#define IDS_OSRPLUGIN 1006
#define IDS_MODALMAIN 1007
#define IDS_MODALDIALOG 1008
#define IDS_EXTENSIONPERF 1009
#define IDS_PERFORMANCE 1009
#define IDS_TRANSPARENCY 1010
// Avoid files associated with MacOS