Add performance tests for CEF V8 methods (issue #484).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@880 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
ce76bfc1e1
commit
95b29d590d
|
@ -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',
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -494,6 +494,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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<CefMenuModel> model) {
|
||||
|
|
|
@ -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 <algorithm>
|
||||
#include <string>
|
||||
|
||||
#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<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<ClientHandler> handler,
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) OVERRIDE {
|
||||
std::string url = request->GetURL();
|
||||
if (url == kTestUrl) {
|
||||
// Show the test contents
|
||||
CefRefPtr<CefStreamReader> 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<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);
|
||||
};
|
||||
|
||||
// Handle bindings in the render process.
|
||||
class RenderDelegate : public ClientApp::RenderDelegate {
|
||||
public:
|
||||
RenderDelegate() {
|
||||
}
|
||||
|
||||
virtual void OnContextCreated(CefRefPtr<ClientApp> app,
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefV8Context> context) OVERRIDE {
|
||||
CefRefPtr<CefV8Value> object = context->GetGlobal();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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<CefBrowser> browser) {
|
||||
// Load the test URL.
|
||||
browser->GetMainFrame()->LoadURL(kTestUrl);
|
||||
}
|
||||
|
||||
} // namespace performance_test
|
|
@ -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<CefBrowser> browser);
|
||||
|
||||
} // namespace performance_test
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_PERFORMANCE_TEST_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_
|
|
@ -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
|
|
@ -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>
|
|
@ -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_
|
||||
|
|
|
@ -49,6 +49,7 @@ CefRefPtr<CefStreamReader> 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},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue