mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-27 10:03:31 +01:00
Update ipc_performance_test to compare similar transfers (see #3502)
This commit is contained in:
parent
e6a96e2bec
commit
15caa9858d
@ -61,9 +61,12 @@ struct ParsedMessage {
|
||||
CefString message;
|
||||
};
|
||||
|
||||
size_t GetByteLength(const CefString& value) {
|
||||
return value.size() * sizeof(CefString::char_type);
|
||||
}
|
||||
|
||||
size_t GetMessageSize(const CefString& response) {
|
||||
return sizeof(MessageHeader) +
|
||||
(response.size() * sizeof(CefString::char_type));
|
||||
return sizeof(MessageHeader) + GetByteLength(response);
|
||||
}
|
||||
|
||||
void CopyResponseIntoMemory(void* memory, const CefString& response) {
|
||||
@ -126,7 +129,7 @@ CefRefPtr<CefProcessMessage> BuildMessage(size_t threshold,
|
||||
int context_id,
|
||||
int request_id,
|
||||
const CefString& response) {
|
||||
if (response.size() <= threshold) {
|
||||
if (GetByteLength(response) <= threshold) {
|
||||
return BuildListMessage(message_name, context_id, request_id, response);
|
||||
} else {
|
||||
return BuildBinaryMessage(message_name, context_id, request_id, response);
|
||||
|
@ -285,18 +285,18 @@ void OnTestSMRProcessMessageReceived(
|
||||
static_cast<const bv_utils::RendererMessage*>(region->Memory());
|
||||
const auto message_size =
|
||||
std::max(region->Size(), sizeof(bv_utils::BrowserMessage));
|
||||
const auto renderer_time = renderer_msg->start_time;
|
||||
const auto duration = finish_time - renderer_time;
|
||||
const auto start_time = bv_utils::Now();
|
||||
|
||||
std::vector<uint8_t> data(message_size);
|
||||
const auto browser_msg =
|
||||
reinterpret_cast<bv_utils::BrowserMessage*>(data.data());
|
||||
browser_msg->test_id = renderer_msg->test_id;
|
||||
browser_msg->duration = finish_time - renderer_msg->start_time;
|
||||
browser_msg->start_time = bv_utils::Now();
|
||||
|
||||
auto builder = CefSharedProcessMessageBuilder::Create(
|
||||
bv_utils::kTestSendSMRProcessMessage, message_size);
|
||||
|
||||
const auto browser_msg =
|
||||
static_cast<bv_utils::BrowserMessage*>(builder->Memory());
|
||||
browser_msg->test_id = renderer_msg->test_id;
|
||||
browser_msg->duration = duration;
|
||||
browser_msg->start_time = start_time;
|
||||
bv_utils::CopyDataIntoMemory(data, builder->Memory());
|
||||
|
||||
frame->SendProcessMessage(PID_RENDERER, builder->Build());
|
||||
}
|
||||
|
@ -207,15 +207,17 @@ class IpcDelegate final : public client::ClientAppRenderer::Delegate {
|
||||
|
||||
const auto buffer_size =
|
||||
std::max(message_size, sizeof(bv_utils::RendererMessage));
|
||||
const auto start_time = bv_utils::Now();
|
||||
|
||||
std::vector<uint8_t> buffer(buffer_size);
|
||||
const auto renderer_msg =
|
||||
reinterpret_cast<bv_utils::RendererMessage*>(buffer.data());
|
||||
renderer_msg->test_id = test_id;
|
||||
renderer_msg->start_time = bv_utils::Now();
|
||||
|
||||
auto builder = CefSharedProcessMessageBuilder::Create(
|
||||
bv_utils::kTestSendSMRProcessMessage, buffer_size);
|
||||
|
||||
auto renderer_msg =
|
||||
static_cast<bv_utils::RendererMessage*>(builder->Memory());
|
||||
renderer_msg->test_id = test_id;
|
||||
renderer_msg->start_time = start_time;
|
||||
bv_utils::CopyDataIntoMemory(buffer, builder->Memory());
|
||||
|
||||
frame->SendProcessMessage(PID_BROWSER, builder->Build());
|
||||
}
|
||||
@ -229,8 +231,8 @@ class IpcDelegate final : public client::ClientAppRenderer::Delegate {
|
||||
|
||||
CefString code = "testSendProcessMessageResult(" +
|
||||
std::to_string(msg.test_id) + ", " +
|
||||
bv_utils::ToMilliString(rendered_to_browser) + ", " +
|
||||
bv_utils::ToMilliString(browser_to_rendered) + ");";
|
||||
bv_utils::ToMicroSecString(rendered_to_browser) + ", " +
|
||||
bv_utils::ToMicroSecString(browser_to_rendered) + ");";
|
||||
|
||||
frame->ExecuteJavaScript(code, frame->GetURL(), 0);
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>IPC Performance Tests</title>
|
||||
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
|
||||
<script src="https://cdn.plot.ly/plotly-2.26.0.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: Tahoma, Serif;
|
||||
@ -70,8 +71,8 @@
|
||||
<td>
|
||||
<p>
|
||||
There is no progress indication of the tests because it
|
||||
significantly influences measurements. <br />It usually takes 30
|
||||
seconds (for 100 samples) to complete the tests. <br /><b>AL</b> -
|
||||
significantly influences measurements. <br />It usually takes 15
|
||||
seconds (for 1000 samples) to complete the tests. <br /><b>AL</b> -
|
||||
ArgumentList-based process messages. <b>SM</b> -
|
||||
SharedMemoryRegion-based process messages.
|
||||
</p>
|
||||
@ -83,7 +84,7 @@
|
||||
<input
|
||||
id="sSamples"
|
||||
type="text"
|
||||
value="100"
|
||||
value="1000"
|
||||
required
|
||||
pattern="[0-9]+"
|
||||
/>
|
||||
@ -97,8 +98,8 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="center" style="width: 8%">Message Size</td>
|
||||
<td class="center" style="width: 8%">AL Round Trip Avg, ms</td>
|
||||
<td class="center" style="width: 8%">SM Round Trip Avg, ms</td>
|
||||
<td class="center" style="width: 8%">AL Round Trip Avg, μs</td>
|
||||
<td class="center" style="width: 8%">SM Round Trip Avg, μs</td>
|
||||
<td class="center" style="width: 10%">Relative Trip Difference</td>
|
||||
<td class="center" style="width: 8%">AL Speed, MB/s</td>
|
||||
<td class="center" style="width: 8%">SM Speed, MB/s</td>
|
||||
@ -126,27 +127,18 @@
|
||||
let box_plot_test_data = [];
|
||||
let round_trip_avg_plot_data = [];
|
||||
|
||||
function nextTest(test) {
|
||||
setTimeout(() => {
|
||||
execNextTest(test.index);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function testSendProcessMessageResult(
|
||||
testIndex,
|
||||
fromRendererToBrowser,
|
||||
fromBrowserToRenderer
|
||||
) {
|
||||
const test = tests[testIndex];
|
||||
|
||||
const roundTrip = fromRendererToBrowser + fromBrowserToRenderer;
|
||||
test.totalRoundTrip += roundTrip;
|
||||
test.sample++;
|
||||
box_plot_test_data[testIndex].x.push(roundTrip);
|
||||
|
||||
setTimeout(() => {
|
||||
execTest(testIndex);
|
||||
}, 10);
|
||||
setTimeout(execTest, 0, testIndex);
|
||||
}
|
||||
|
||||
function sendRequest(size, testIndex) {
|
||||
@ -176,10 +168,10 @@
|
||||
const test = tests[testIndex];
|
||||
|
||||
if (test.sample >= test.totalSamples) {
|
||||
return nextTest(test);
|
||||
setTimeout(execNextTest, 0, testIndex);
|
||||
} else {
|
||||
test.func(test.messageSize, test.index);
|
||||
}
|
||||
|
||||
test.func(test.index);
|
||||
}
|
||||
|
||||
function column(prepared, value) {
|
||||
@ -269,8 +261,8 @@
|
||||
((avgRoundTripSMR - avgRoundTrip) / avgRoundTrip) * 100;
|
||||
|
||||
// In MB/s
|
||||
const speed = test.messageSize / (avgRoundTrip * 1000);
|
||||
const speedSMR = testSMR.messageSize / (avgRoundTripSMR * 1000);
|
||||
const speed = test.messageSize / avgRoundTrip;
|
||||
const speedSMR = testSMR.messageSize / avgRoundTripSMR;
|
||||
const relativeSpeedDiff = ((speedSMR - speed) / speed) * 100;
|
||||
|
||||
const stdDeviation = getStandardDeviation(
|
||||
@ -362,16 +354,16 @@
|
||||
function execNextTest(testIndex) {
|
||||
testIndex++;
|
||||
if (tests.length <= testIndex) {
|
||||
return testSuiteFinished();
|
||||
testSuiteFinished();
|
||||
} else {
|
||||
return execTest(testIndex);
|
||||
execTest(testIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function execQueuedTests(totalSamples) {
|
||||
prepareQueuedTests(totalSamples);
|
||||
// Let the updated table render before starting the tests
|
||||
setTimeout(() => execNextTest(-1), 200);
|
||||
setTimeout(execNextTest, 200, -1);
|
||||
}
|
||||
|
||||
function setSettingsState(disabled) {
|
||||
@ -401,7 +393,6 @@
|
||||
|
||||
function humanFileSize(bytes) {
|
||||
const step = 1024;
|
||||
const originalBytes = bytes;
|
||||
|
||||
if (Math.abs(bytes) < step) {
|
||||
return bytes + " B";
|
||||
@ -432,17 +423,12 @@
|
||||
};
|
||||
|
||||
for (let size = 512; size <= 512 * 1024; size = size * 2) {
|
||||
queueTest(humanFileSize(size) + " AL", size, (testIndex) =>
|
||||
sendRequest(size, testIndex)
|
||||
);
|
||||
|
||||
queueTest(humanFileSize(size) + " SM", size, (testIndex) =>
|
||||
sendSMRRequest(size, testIndex)
|
||||
);
|
||||
queueTest(humanFileSize(size) + " AL", size, sendRequest);
|
||||
queueTest(humanFileSize(size) + " SM", size, sendSMRRequest);
|
||||
}
|
||||
|
||||
const totalSamples = parseInt(document.getElementById("sSamples").value);
|
||||
prepareQueuedTests(totalSamples);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -7,26 +7,24 @@
|
||||
namespace {
|
||||
|
||||
constexpr int kSingleQueryErrorCode = 5;
|
||||
constexpr size_t kMessageSizeThreshold = 16000;
|
||||
constexpr size_t kMsgSizeThresholdInBytes = 16000;
|
||||
constexpr auto kCharSize = sizeof(CefString::char_type);
|
||||
|
||||
enum class TestType { SUCCESS, FAILURE };
|
||||
|
||||
CefString GenerateResponse(size_t size, char ch) {
|
||||
return CefString(std::string(size, ch));
|
||||
CefString GenerateResponse(size_t count, char ch) {
|
||||
return std::string(count, ch);
|
||||
}
|
||||
|
||||
CefString GenerateResponse(size_t size, wchar_t ch) {
|
||||
return CefString(std::wstring(size, ch));
|
||||
CefString GenerateResponse(size_t count, wchar_t ch) {
|
||||
return std::wstring(count, ch);
|
||||
}
|
||||
|
||||
template <class CharType>
|
||||
class ThresholdTestHandler final : public SingleLoadTestHandler {
|
||||
public:
|
||||
ThresholdTestHandler(TestType type, size_t message_size, CharType symbol)
|
||||
: test_type_(type),
|
||||
message_size_(message_size),
|
||||
message_size_str_(std::to_string(message_size)),
|
||||
symbol_(symbol) {}
|
||||
ThresholdTestHandler(TestType type, size_t string_length, CharType symbol)
|
||||
: test_type_(type), string_length_(string_length), symbol_(symbol) {}
|
||||
|
||||
std::string GetMainHTML() override {
|
||||
const std::string& errorCodeStr = std::to_string(kSingleQueryErrorCode);
|
||||
@ -35,7 +33,8 @@ class ThresholdTestHandler final : public SingleLoadTestHandler {
|
||||
"<html><body><script>\n"
|
||||
// Send the query.
|
||||
"var request_id = window." +
|
||||
std::string(kJSQueryFunc) + "({\n request: '" + message_size_str_ +
|
||||
std::string(kJSQueryFunc) + "({\n request: '" +
|
||||
std::to_string(string_length_) +
|
||||
"',\n persistent: false,\n"
|
||||
" onSuccess: function(response) {\n"
|
||||
" window.mrtNotify(response);\n"
|
||||
@ -63,7 +62,7 @@ class ThresholdTestHandler final : public SingleLoadTestHandler {
|
||||
EXPECT_FALSE(got_notify_);
|
||||
got_notify_.yes();
|
||||
|
||||
auto expected = GenerateResponse(message_size_, symbol_);
|
||||
auto expected = GenerateResponse(string_length_, symbol_);
|
||||
|
||||
switch (test_type_) {
|
||||
case TestType::SUCCESS:
|
||||
@ -108,7 +107,7 @@ class ThresholdTestHandler final : public SingleLoadTestHandler {
|
||||
AssertMainFrame(frame);
|
||||
EXPECT_NE(0, query_id);
|
||||
EXPECT_FALSE(persistent);
|
||||
EXPECT_EQ(message_size_str_, request.ToString());
|
||||
EXPECT_EQ(std::to_string(string_length_), request.ToString());
|
||||
|
||||
const size_t message_size =
|
||||
static_cast<size_t>(std::stoi(request.ToString()));
|
||||
@ -130,8 +129,7 @@ class ThresholdTestHandler final : public SingleLoadTestHandler {
|
||||
|
||||
private:
|
||||
const TestType test_type_;
|
||||
const size_t message_size_;
|
||||
const std::string message_size_str_;
|
||||
const size_t string_length_;
|
||||
const CharType symbol_;
|
||||
|
||||
CefRefPtr<Callback> callback_;
|
||||
@ -149,20 +147,22 @@ using WCharTestHandlerPtr = CefRefPtr<WCharTestHandler>;
|
||||
} // namespace
|
||||
|
||||
TEST(MessageRouterTest, ThresholdMessageUnderSuccessCallback) {
|
||||
const auto UnderThreshold = kMessageSizeThreshold - 1;
|
||||
const auto under_threshold = kMsgSizeThresholdInBytes - kCharSize;
|
||||
const auto string_length = under_threshold / kCharSize;
|
||||
CharTestHandlerPtr handler =
|
||||
new CharTestHandler(TestType::SUCCESS, UnderThreshold, 'A');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new CharTestHandler(TestType::SUCCESS, string_length, 'A');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, ThresholMessageExactdSuccessCallback) {
|
||||
TEST(MessageRouterTest, ThresholdMessageExactSuccessCallback) {
|
||||
const auto string_length = kMsgSizeThresholdInBytes / kCharSize;
|
||||
CharTestHandlerPtr handler =
|
||||
new CharTestHandler(TestType::SUCCESS, kMessageSizeThreshold, 'A');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new CharTestHandler(TestType::SUCCESS, string_length, 'A');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
@ -170,10 +170,11 @@ TEST(MessageRouterTest, ThresholMessageExactdSuccessCallback) {
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, ThresholdMessageOverSuccessCallback) {
|
||||
const auto OverThreshold = kMessageSizeThreshold + 1;
|
||||
const auto over_threshold = kMsgSizeThresholdInBytes + kCharSize;
|
||||
const auto string_length = over_threshold / kCharSize;
|
||||
CharTestHandlerPtr handler =
|
||||
new CharTestHandler(TestType::SUCCESS, OverThreshold, 'A');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new CharTestHandler(TestType::SUCCESS, string_length, 'A');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
@ -181,21 +182,23 @@ TEST(MessageRouterTest, ThresholdMessageOverSuccessCallback) {
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, ThresholdMessageUnderFailureCallback) {
|
||||
const auto UnderThreshold = kMessageSizeThreshold - 1;
|
||||
const auto under_threshold = kMsgSizeThresholdInBytes - kCharSize;
|
||||
const auto string_length = under_threshold / kCharSize;
|
||||
CharTestHandlerPtr handler =
|
||||
new CharTestHandler(TestType::FAILURE, UnderThreshold, 'A');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new CharTestHandler(TestType::FAILURE, string_length, 'A');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, ThresholMessageOverdFailureCallback) {
|
||||
const auto OverThreshold = kMessageSizeThreshold + 1;
|
||||
TEST(MessageRouterTest, ThresholdMessageOverFailureCallback) {
|
||||
const auto over_threshold = kMsgSizeThresholdInBytes + kCharSize;
|
||||
const auto string_length = over_threshold / kCharSize;
|
||||
CharTestHandlerPtr handler =
|
||||
new CharTestHandler(TestType::FAILURE, OverThreshold, 'A');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new CharTestHandler(TestType::FAILURE, string_length, 'A');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
@ -203,10 +206,11 @@ TEST(MessageRouterTest, ThresholMessageOverdFailureCallback) {
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, ThresholdUtf8MessageUnderSuccessCallback) {
|
||||
const auto UnderThreshold = kMessageSizeThreshold - 1;
|
||||
const auto under_threshold = kMsgSizeThresholdInBytes - kCharSize;
|
||||
const auto string_length = under_threshold / kCharSize;
|
||||
WCharTestHandlerPtr handler =
|
||||
new WCharTestHandler(TestType::SUCCESS, UnderThreshold, L'\u304B');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new WCharTestHandler(TestType::SUCCESS, string_length, L'\u304B');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
@ -214,10 +218,11 @@ TEST(MessageRouterTest, ThresholdUtf8MessageUnderSuccessCallback) {
|
||||
}
|
||||
|
||||
TEST(MessageRouterTest, ThresholdUtf8MessageOverSuccessCallback) {
|
||||
const auto OverThreshold = kMessageSizeThreshold + 1;
|
||||
const auto over_threshold = kMsgSizeThresholdInBytes + kCharSize;
|
||||
const auto string_length = over_threshold / kCharSize;
|
||||
WCharTestHandlerPtr handler =
|
||||
new WCharTestHandler(TestType::SUCCESS, OverThreshold, L'\u304B');
|
||||
handler->SetMessageSizeThreshold(kMessageSizeThreshold);
|
||||
new WCharTestHandler(TestType::SUCCESS, string_length, L'\u304B');
|
||||
handler->SetMessageSizeThreshold(kMsgSizeThresholdInBytes);
|
||||
|
||||
handler->ExecuteTest();
|
||||
|
||||
|
@ -18,6 +18,10 @@ CefRefPtr<CefBinaryValue> CreateCefBinaryValue(
|
||||
return CefBinaryValue::Create(data.data(), data.size());
|
||||
}
|
||||
|
||||
void CopyDataIntoMemory(const std::vector<uint8_t>& data, void* dst) {
|
||||
memcpy(dst, data.data(), data.size());
|
||||
}
|
||||
|
||||
RendererMessage GetRendererMsgFromBinary(
|
||||
const CefRefPtr<CefBinaryValue>& value) {
|
||||
DCHECK_GE(value->GetSize(), sizeof(RendererMessage));
|
||||
@ -33,9 +37,9 @@ BrowserMessage GetBrowserMsgFromBinary(const CefRefPtr<CefBinaryValue>& value) {
|
||||
return *reinterpret_cast<const BrowserMessage*>(data.data());
|
||||
}
|
||||
|
||||
std::string ToMilliString(const Duration& duration) {
|
||||
std::string ToMicroSecString(const Duration& duration) {
|
||||
const auto ms =
|
||||
std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
|
||||
std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(
|
||||
duration);
|
||||
|
||||
return std::to_string(ms.count());
|
||||
|
@ -35,12 +35,14 @@ TimePoint Now();
|
||||
CefRefPtr<CefBinaryValue> CreateCefBinaryValue(
|
||||
const std::vector<uint8_t>& data);
|
||||
|
||||
void CopyDataIntoMemory(const std::vector<uint8_t>& data, void* dst);
|
||||
|
||||
RendererMessage GetRendererMsgFromBinary(
|
||||
const CefRefPtr<CefBinaryValue>& value);
|
||||
|
||||
BrowserMessage GetBrowserMsgFromBinary(const CefRefPtr<CefBinaryValue>& value);
|
||||
|
||||
std::string ToMilliString(const Duration& duration);
|
||||
std::string ToMicroSecString(const Duration& duration);
|
||||
|
||||
} // namespace bv_utils
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user