Skip to content

Commit

Permalink
Make test_scheduler more smart (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
victimsnino authored Sep 26, 2022
1 parent b7daaf7 commit 189556d
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 49 deletions.
95 changes: 78 additions & 17 deletions src/tests/test_interval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,106 @@
SCENARIO("interval emit values with provided interval", "[interval]")
{
auto scheduler = test_scheduler{};
auto mock = mock_observer<size_t>{};
auto mock = mock_observer<size_t>{};
GIVEN("interval observable")
{
auto interval = std::chrono::seconds{ 1 };
auto obs = rpp::source::interval(interval, scheduler);
auto interval = std::chrono::seconds{1};
auto obs = rpp::source::interval(interval, scheduler);
auto initial_time = test_scheduler::worker_strategy::now();

WHEN("subscribe on it via take 3")
{
obs.take(3).subscribe(mock);
THEN("observer obtains sequence of values")
THEN("nothing happens immediately till scheduler advanced")
{
CHECK(mock.get_received_values() == std::vector<size_t>{0, 1, 2});
CHECK(mock.get_received_values() == std::vector<size_t>{});
CHECK(mock.get_on_error_count() == 0);
CHECK(mock.get_on_completed_count() == 1);
CHECK(mock.get_on_completed_count() == 0);
CHECK(scheduler.get_schedulings() == std::vector{ initial_time + interval});
CHECK(scheduler.get_executions().empty());
}
AND_WHEN("move time in advance on interval once")
{
scheduler.time_advance(interval);
THEN("observer obtains first value")
{
CHECK(mock.get_received_values() == std::vector<size_t>{0});
CHECK(mock.get_on_error_count() == 0);
CHECK(mock.get_on_completed_count() == 0);
}
THEN("interval schedules schedulable with provided interval")
{
CHECK(scheduler.get_schedulings() == std::vector{ initial_time + interval,
initial_time + 2*interval});
CHECK(scheduler.get_executions() == std::vector{initial_time+interval});
}
}
THEN("interval schedules schedulable with provided interval")
AND_WHEN("move time in advance on interval enough amount of time")
{
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time + interval, s_current_time + 2*interval, s_current_time + 3*interval});
for (size_t i = 0; i < 5; ++i)
scheduler.time_advance(interval);

THEN("observer obtains sequence of values")
{
CHECK(mock.get_received_values() == std::vector<size_t>{0, 1, 2});
CHECK(mock.get_on_error_count() == 0);
CHECK(mock.get_on_completed_count() == 1);
}
THEN("interval schedules schedulable with provided interval")
{
CHECK(scheduler.get_executions() == std::vector{ initial_time + interval,
initial_time + 2*interval,
initial_time + 3*interval});
CHECK(scheduler.get_schedulings() == std::vector{ initial_time + interval,
initial_time + 2*interval,
initial_time + 3*interval,
initial_time + 4*interval});
}
}
}
}

GIVEN("interval observable with initial delay")
{
auto initial_delay = std::chrono::seconds{ 2 };
auto interval = std::chrono::seconds{ 1 };
auto obs = rpp::source::interval(initial_delay, interval, scheduler);
auto initial_delay = std::chrono::seconds{2};
auto interval = std::chrono::seconds{1};
auto obs = rpp::source::interval(initial_delay, interval, scheduler);
auto initial_time = test_scheduler::worker_strategy::now();

WHEN("subscribe on it via take 3")
{
obs.take(3).subscribe(mock);
THEN("observer obtains sequence of values")
THEN("nothing happens immediately till scheduler advanced")
{
CHECK(mock.get_received_values() == std::vector<size_t>{0, 1, 2});
CHECK(mock.get_received_values() == std::vector<size_t>{});
CHECK(mock.get_on_error_count() == 0);
CHECK(mock.get_on_completed_count() == 1);
CHECK(mock.get_on_completed_count() == 0);
CHECK(scheduler.get_schedulings() == std::vector{ initial_time + initial_delay});
CHECK(scheduler.get_executions().empty());
}
THEN("interval schedules schedulable with provided interval")

AND_WHEN("move time in advance on interval enough amount of time")
{
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time + initial_delay, s_current_time + initial_delay + interval, s_current_time + initial_delay + 2 * interval });
for (size_t i = 0; i < 5; ++i)
scheduler.time_advance(interval);
scheduler.time_advance(interval);
THEN("observer obtains sequence of values")
{
CHECK(mock.get_received_values() == std::vector<size_t>{0, 1, 2});
CHECK(mock.get_on_error_count() == 0);
CHECK(mock.get_on_completed_count() == 1);
}
THEN("interval schedules schedulable with provided interval")
{
CHECK(scheduler.get_schedulings() == std::vector{ initial_time + initial_delay,
initial_time + initial_delay + interval,
initial_time + initial_delay + 2 * interval,
initial_time + initial_delay + 3 * interval });
CHECK(scheduler.get_executions() == std::vector{ initial_time + initial_delay,
initial_time + initial_delay + interval,
initial_time + initial_delay + 2 * interval });
}
}
}
}
}
}
10 changes: 7 additions & 3 deletions src/tests/test_observe_on.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ SCENARIO("observe_on transfers emssions to scheduler", "[operators][observe_on]"
{
auto mock = mock_observer<std::string>{};
auto scheduler = test_scheduler{};
auto initial_time = test_scheduler::worker_strategy::now();

GIVEN("observable with item")
{
Expand All @@ -38,7 +39,8 @@ SCENARIO("observe_on transfers emssions to scheduler", "[operators][observe_on]"

CHECK(mock.get_received_values() == vals);
CHECK(mock.get_on_completed_count() == 1);
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time, s_current_time, s_current_time });//2 items + on_completed
CHECK(scheduler.get_schedulings() == std::vector{ initial_time, initial_time, initial_time });//2 items + on_completed
CHECK(scheduler.get_executions() == std::vector{ initial_time, initial_time, initial_time });//2 items + on_completed
}
}
}
Expand All @@ -56,7 +58,8 @@ SCENARIO("observe_on transfers emssions to scheduler", "[operators][observe_on]"

CHECK(mock.get_on_error_count() == 1);
CHECK(mock.get_on_completed_count() == 0);
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time });
CHECK(scheduler.get_schedulings() == std::vector{ initial_time });
CHECK(scheduler.get_executions() == std::vector{ initial_time });

}
}
Expand All @@ -76,7 +79,8 @@ SCENARIO("observe_on transfers emssions to scheduler", "[operators][observe_on]"
CHECK(mock.get_total_on_next_count() == 0);
CHECK(mock.get_on_error_count() == 0);
CHECK(mock.get_on_completed_count() == 1);
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time });
CHECK(scheduler.get_schedulings() == std::vector{ initial_time });
CHECK(scheduler.get_executions() == std::vector{ initial_time });

}
}
Expand Down
80 changes: 59 additions & 21 deletions src/tests/test_scheduler.hpp
Original file line number Diff line number Diff line change
@@ -1,58 +1,96 @@
// ReactivePlusPlus library
//
//
// Copyright Aleksey Loginov 2022 - present.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
//
//
// Project home: https://github.com/victimsnino/ReactivePlusPlus

#pragma once

#include <rpp/schedulers.hpp>

static rpp::schedulers::time_point s_current_time{ std::chrono::seconds{0} };
static rpp::schedulers::time_point s_current_time{std::chrono::seconds{0}};

class test_scheduler final : public rpp::schedulers::details::scheduler_tag
{
public:
class worker_strategy
struct state
{
public:
worker_strategy(const rpp::subscription_base& sub,
std::shared_ptr<std::vector<rpp::schedulers::time_point>> schedulings)
: m_sub{ sub }
, m_schedulings{ schedulings } {}
state() = default;

void schedule(rpp::schedulers::time_point time_point,
rpp::schedulers::constraint::schedulable_fn auto&& fn)
{
schedulings.push_back(time_point);
queue.emplace(time_point,
static_cast<size_t>(rpp::schedulers::clock_type::now().time_since_epoch().count()),
std::forward<decltype(fn)>(fn));
}

void defer_at(rpp::schedulers::time_point time_point, rpp::schedulers::constraint::schedulable_fn auto&& fn) const
void drain()
{
while (m_sub.is_subscribed())
while (!queue.empty() && sub.is_subscribed())
{
m_schedulings->push_back(time_point);
auto time_point = queue.top().get_time_point();
if (time_point > s_current_time)
return;

auto fn = queue.top().extract_function();
queue.pop();

executions.push_back(s_current_time);
if (auto duration = fn())
time_point = std::max(now(), time_point + duration.value());
else
return;
schedule(std::max(s_current_time, time_point + duration.value()), std::move(fn));
}
}

rpp::subscription_base sub{};
std::vector<rpp::schedulers::time_point> schedulings{};
std::vector<rpp::schedulers::time_point> executions{};
std::priority_queue<rpp::schedulers::details::schedulable<std::function<rpp::schedulers::optional_duration()>>> queue{};
};

class worker_strategy
{
public:
worker_strategy(std::shared_ptr<state> state)
: m_state{state} { }

void defer_at(rpp::schedulers::time_point time_point,
rpp::schedulers::constraint::schedulable_fn auto&& fn) const
{
if (m_state->sub.is_subscribed())
{
m_state->schedule(time_point, std::forward<decltype(fn)>(fn));
m_state->drain();
}
}

static rpp::schedulers::time_point now() { return s_current_time; }

private:
rpp::subscription_base m_sub;
std::shared_ptr<std::vector<rpp::schedulers::time_point>> m_schedulings;
std::shared_ptr<state> m_state;
};

test_scheduler() {}

rpp::schedulers::worker<worker_strategy> create_worker(const rpp::subscription_base& sub = {}) const
{
return rpp::schedulers::worker<worker_strategy>{sub, m_schedulings};
m_state->sub = sub;
return rpp::schedulers::worker<worker_strategy>{m_state};
}

const auto& get_schedulings() const { return *m_schedulings; }
const auto& get_schedulings() const { return m_state->schedulings; }
const auto& get_executions() const { return m_state->executions; }

void time_advance(rpp::schedulers::duration dur) const
{
s_current_time += dur;
m_state->drain();
}

private:
std::shared_ptr<std::vector<rpp::schedulers::time_point>> m_schedulings = std::make_shared<std::vector<rpp::schedulers::time_point>>();
};
std::shared_ptr<state> m_state = std::make_shared<state>();
};
28 changes: 22 additions & 6 deletions src/tests/test_schedulers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,34 @@ SCENARIO("scheduler's worker uses time")
GIVEN("test scheduler")
{
auto scheduler = test_scheduler{};
auto initial_time = test_scheduler::worker_strategy::now();

WHEN("Schedule action without time")
{
scheduler.create_worker().schedule([] { return rpp::schedulers::optional_duration{}; });
THEN("worker obtains schedulable once with current time")
{
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time });
CHECK(scheduler.get_schedulings() == std::vector{ initial_time });
CHECK(scheduler.get_executions() == std::vector{ initial_time });
}
}
WHEN("Schedule action with some time")
{
auto time = rpp::schedulers::clock_type::now();
scheduler.create_worker().schedule(time, [] { return rpp::schedulers::optional_duration{}; });
THEN("worker obtains schedulable once with provided time")
auto dur = std::chrono::seconds{3};
scheduler.create_worker().schedule(initial_time+dur, [] { return rpp::schedulers::optional_duration{}; });
THEN("worker obtains schedulable once with provided time, but not execute till time advanced")
{
CHECK(scheduler.get_schedulings() == std::vector{ time });
CHECK(scheduler.get_schedulings() == std::vector{ initial_time+dur });
CHECK(scheduler.get_executions().empty());
AND_WHEN("time advanced")
{
scheduler.time_advance(dur+std::chrono::seconds{1});
THEN("scheduler executes schedulable")
{
CHECK(scheduler.get_executions() == std::vector{ initial_time+dur+std::chrono::seconds{1} });
}
}

}
}
WHEN("Schedule action with zero duration")
Expand Down Expand Up @@ -107,9 +120,12 @@ SCENARIO("scheduler's worker uses time")
return std::nullopt;
return dur;
});
for(size_t i = 0; i < 3;++i)
scheduler.time_advance(dur);

THEN("worker obtains schedulable three times with current time and time+diff")
{
CHECK(scheduler.get_schedulings() == std::vector{ s_current_time, s_current_time + dur , s_current_time + dur + dur });
CHECK(scheduler.get_schedulings() == std::vector{ initial_time, initial_time + dur , initial_time + dur + dur });
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/tests/test_subscribe_on.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ TEST_CASE("subscribe_on schedules job in another scheduler")
{
auto mock = mock_observer<int>{};
auto scheduler = test_scheduler{};
auto initial_time = test_scheduler::worker_strategy::now();

GIVEN("observable")
{
auto obs = rpp::source::create<int>([&](const auto& sub)
Expand All @@ -35,7 +37,8 @@ TEST_CASE("subscribe_on schedules job in another scheduler")
{
REQUIRE(mock.get_total_on_next_count() == 1);
REQUIRE(mock.get_on_completed_count() == 1);
REQUIRE(scheduler.get_schedulings() == std::vector{ s_current_time });
REQUIRE(scheduler.get_schedulings() == std::vector{ initial_time });
REQUIRE(scheduler.get_executions() == std::vector{ initial_time });
}
}
}
Expand All @@ -50,7 +53,8 @@ TEST_CASE("subscribe_on schedules job in another scheduler")
REQUIRE(mock.get_total_on_next_count() == 0);
REQUIRE(mock.get_on_error_count() == 1);
REQUIRE(mock.get_on_completed_count() == 0);
REQUIRE(scheduler.get_schedulings() == std::vector{ s_current_time });
REQUIRE(scheduler.get_schedulings() == std::vector{ initial_time });
REQUIRE(scheduler.get_executions() == std::vector{ initial_time });
}
}
}
Expand Down

1 comment on commit 189556d

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BENCHMARK RESULTS (AUTOGENERATED)

ci-ubuntu-clang

Observable construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable construction 0.33ns 0.303457 1.10 0.34ns
Dynamic observable construction 29.16ns 31.037 0.94 24.46ns
Specific observable construction + as_dynamic 29.17ns 33.7438 0.86 24.51ns

Observable lift

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable lift specific observer 110.65ns 139.16 0.80 291.13ns
Specific observable lift dynamic observer 136.66ns 162.989 0.84 318.98ns
Dynamic observable lift specific observer 183.59ns 225.662 0.81 344.99ns
Dynamic observable lift dynamic observer 193.11ns 259.799 0.74 335.94ns

Observable subscribe

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable subscribe specific observer 77.36ns 90.2922 0.86 286.16ns
Specific observable subscribe dynamic observer 88.12ns 90.5164 0.97 310.78ns
Dynamic observable subscribe specific observer 145.71ns 137.234 1.06 338.18ns
Dynamic observable subscribe dynamic observer 146.31ns 163.994 0.89 327.44ns

Observable subscribe #2

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable subscribe lambda 77.23ns 74.0241 1.04 291.03ns
Dynamic observable subscribe lambda 139.73ns 168.534 0.83 325.25ns
Specific observable subscribe lambda without subscription 76.68ns 94.9825 0.81 291.52ns
Dynamic observable subscribe lambda without subscription 139.88ns 135.87 1.03 326.87ns
Specific observable subscribe specific subscriber 43.16ns 58.6207 0.74 233.97ns
Dynamic observable subscribe specific subscriber 105.53ns 128.779 0.82 299.26ns
Specific observable subscribe dynamic observer 43.52ns 48.5686 0.90 240.63ns
Dynamic observable subscribe dynamic observer 96.57ns 96.5568 1.00 267.16ns

Observer construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observer construction 0.34ns 0.324978 1.03 0.34ns
Dynamic observer construction 29.21ns 30.2721 0.96 20.96ns
Specific observer construction + as_dynamic 32.15ns 26.3945 1.22 21.13ns

OnNext

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observer OnNext 0.67ns 0.660469 1.01 0.67ns
Dynamic observer OnNext 1.68ns 2.46779 0.68 2.35ns

Subscriber construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Make subsriber 33.82ns 40.6315 0.83 64.45ns
Make copy of subscriber 16.74ns 21.3113 0.79 4.74ns
Transform subsriber to dynamic 45.87ns 50.3781 0.91 26.80ns

Subscription

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
composite_subscription create 33.84ns 37.3975 0.90 53.31ns
composite_subscription add 49.88ns 66.1178 0.75 93.23ns
composite_subscription unsubscribe 43.34ns 45.1791 0.96 23.44ns

buffer

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
buffer 269.46ns 275.357 0.98 1819.43ns
sending of values from observable via buffer to subscriber 6.40ns 5.67401 1.13 27.36ns

chains creation test

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
long non-state chain creation + subscribe 270.96ns 305.285 0.89 506.99ns
long stateful chain creation + subscribe 399.56ns 439.494 0.91 808.60ns

combine_latest

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
combine_latest construction from observable via dot + subscribe 900.81ns 997.178 0.90 863.13ns
sending of values from observable via combine_latest to subscriber 27.59ns 38.6489 0.71 2.35ns

concat

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
concat 1890.77ns 1803.82 1.05 3430.93ns
concat_with 2220.38ns 2095.51 1.06 3610.60ns

distinct_until_changed

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
distinct_until_changed construction from observable via dot + subscribe 129.04ns 124.883 1.03 249.57ns
sending of values from observable via distinct_until_changed to subscriber 2.68ns 3.17377 0.85 1.34ns

first

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
first construction from observable via dot + subscribe 143.03ns 161.927 0.88 589.14ns
sending of values from observable via first to subscriber 0.67ns 0.443697 1.51 0.67ns

foundamental sources

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
empty 84.85ns 96.4201 0.88 638.22ns
error 135.85ns 145.962 0.93 758.98ns
never 46.87ns 49.1035 0.95 269.91ns

from

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
from vector with int 100.90ns 91.2568 1.11 649.03ns

immediate scheduler

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no any re-schedule 0.67ns 0.473791 1.42 111.96ns
re-schedule 10 times 6.85ns 11.7215 0.58 143.44ns

just

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
just send int 87.78ns 76.4729 1.15 645.07ns
just send variadic 115.94ns 113.962 1.02 735.68ns

last

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
last construction from observable via dot + subscribe 186.01ns 182.873 1.02 364.62ns
sending of values from observable via last to subscriber 2.38ns 2.58301 0.92 1.68ns

map

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
map construction from observable via dot + subscribe 89.02ns 99.0867 0.90 240.29ns
sending of values from observable via map to subscriber 1.01ns 0.853487 1.18 2.34ns

merge

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
merge 1859.90ns 1640.13 1.13 3351.54ns
merge_with 2190.53ns 2027.87 1.08 3532.60ns

observe_on

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
observe_on construction from observable via dot + subscribe 555.96ns 550.072 1.01 2585.03ns
sending of values from observable via observe_on to subscriber 89.93ns 98.7961 0.91 198.53ns

publish_subject callbacks

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
on_next 24.11ns 25.0439 0.96 11.04ns
on_error 0.67ns 0.51916 1.30 19.21ns
on_completed 0.67ns 0.516979 1.30 0.67ns

publish_subject routines

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
construct 196.60ns 226.749 0.87 179.00ns
get_observable 29.12ns 29.6374 0.98 50.65ns
get_subscriber 60.54ns 63.321 0.96 13.66ns

repeat

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
repeat construction from observable via dot + subscribe 3966.93ns 4106.73 0.97 3049.54ns

scan

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
scan construction from observable via dot + subscribe 125.40ns 139.19 0.90 309.46ns
sending of values from observable via scan to subscriber 2.22ns 2.22851 0.99 2.35ns

single-threaded locks

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no-lock increment 2.02ns 2.65033 0.76 .
mutex lock increment 18.08ns 21.9348 0.82 .
spin-lock increment 9.03ns 9.32004 0.97 .

skip

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
skip construction from observable via dot + subscribe 118.43ns 129.047 0.92 474.79ns
sending of values from observable via skip to subscriber 2.01ns 2.22761 0.90 2.01ns

switch_on_next

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
switch_on_next construction from observable via dot + subscribe 2224.33ns 2781.68 0.80 2804.37ns
sending of values from observable via switch_on_next to subscriber 568.82ns 485.095 1.17 639.60ns

take

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take construction from observable via dot + subscribe 186.18ns 196.426 0.95 490.92ns
sending of values from observable via take to subscriber 2.35ns 2.98348 0.79 2.66ns

take_last

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take_last construction from observable via dot + subscribe 230.40ns 251.086 0.92 534.38ns
sending of values from observable via take_last to subscriber 2.91ns 3.2309 0.90 3.48ns

take_until

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take_until construction from observable via dot + subscribe 1056.46ns 1128.04 0.94 1166.78ns
sending of values from observable via take_until to subscriber 9.03ns 10.0262 0.90 2.98ns

trampoline scheduler

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no any re-schedule 11.74ns 13.677 0.86 160.39ns
re-schedule 10 times 30.77ns 26.0061 1.18 193.29ns
recursively schedule 10 times 1388.93ns 1605.01 0.87 5632.23ns

window

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
window 2024.02ns 1942.01 1.04 3143.04ns
sending of values from observable via window to subscriber 547.04ns 566.532 0.97 365.92ns

with_latest_from

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
with_latest_from construction from observable via dot + subscribe 1041.47ns 1151.64 0.90 1113.56ns
sending of values from observable via with_latest_from to subscriber 26.40ns 30.0511 0.88 3.01ns

ci-ubuntu-gcc

Observable construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable construction 0.34ns 0.363711 0.92 0.34ns
Dynamic observable construction 31.64ns 30.2307 1.05 22.77ns
Specific observable construction + as_dynamic 31.70ns 33.2659 0.95 23.30ns

Observable lift

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable lift specific observer 119.11ns 121.073 0.98 331.43ns
Specific observable lift dynamic observer 145.42ns 164.567 0.88 346.35ns
Dynamic observable lift specific observer 198.58ns 215.382 0.92 385.80ns
Dynamic observable lift dynamic observer 207.97ns 221.038 0.94 383.18ns

Observable subscribe

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable subscribe specific observer 82.82ns 86.1006 0.96 320.81ns
Specific observable subscribe dynamic observer 95.27ns 101.666 0.94 330.33ns
Dynamic observable subscribe specific observer 150.02ns 178.482 0.84 363.97ns
Dynamic observable subscribe dynamic observer 146.12ns 159.363 0.92 345.33ns

Observable subscribe #2

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable subscribe lambda 83.35ns 81.1403 1.03 330.94ns
Dynamic observable subscribe lambda 151.26ns 169.625 0.89 379.30ns
Specific observable subscribe lambda without subscription 83.48ns 91.5542 0.91 320.88ns
Dynamic observable subscribe lambda without subscription 151.03ns 155.137 0.97 365.87ns
Specific observable subscribe specific subscriber 50.27ns 51.7139 0.97 271.36ns
Dynamic observable subscribe specific subscriber 118.35ns 120.547 0.98 314.72ns
Specific observable subscribe dynamic observer 50.22ns 50.4471 1.00 274.25ns
Dynamic observable subscribe dynamic observer 102.30ns 128.199 0.80 287.87ns

Observer construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observer construction 0.34ns 0.399176 0.84 0.34ns
Dynamic observer construction 31.44ns 35.7399 0.88 21.00ns
Specific observer construction + as_dynamic 31.50ns 36.3258 0.87 20.41ns

OnNext

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observer OnNext 0.33ns 0.383102 0.87 0.34ns
Dynamic observer OnNext 1.67ns 2.42721 0.69 2.01ns

Subscriber construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Make subsriber 34.72ns 38.4586 0.90 63.01ns
Make copy of subscriber 16.72ns 24.918 0.67 4.45ns
Transform subsriber to dynamic 45.10ns 45.7498 0.99 25.48ns

Subscription

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
composite_subscription create 36.88ns 37.7443 0.98 54.97ns
composite_subscription add 47.44ns 45.9564 1.03 97.21ns
composite_subscription unsubscribe 41.59ns 50.3341 0.83 22.11ns

buffer

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
buffer 264.98ns 293.496 0.90 1894.52ns
sending of values from observable via buffer to subscriber 7.41ns 10.44 0.71 30.43ns

chains creation test

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
long non-state chain creation + subscribe 301.77ns 318.576 0.95 671.52ns
long stateful chain creation + subscribe 433.38ns 582.68 0.74 1044.89ns

combine_latest

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
combine_latest construction from observable via dot + subscribe 950.94ns 1059.62 0.90 1073.15ns
sending of values from observable via combine_latest to subscriber 27.47ns 32.3871 0.85 2.36ns

concat

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
concat 1943.77ns 2112.94 0.92 3652.15ns
concat_with 2292.02ns 3043.18 0.75 4087.17ns

distinct_until_changed

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
distinct_until_changed construction from observable via dot + subscribe 137.65ns 146.633 0.94 351.25ns
sending of values from observable via distinct_until_changed to subscriber 3.88ns 3.47759 1.12 1.34ns

first

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
first construction from observable via dot + subscribe 161.95ns 182.522 0.89 693.30ns
sending of values from observable via first to subscriber 1.34ns 0.745617 1.80 1.01ns

foundamental sources

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
empty 94.36ns 106.859 0.88 734.79ns
error 136.10ns 159.199 0.85 837.23ns
never 49.50ns 53.4859 0.93 281.02ns

from

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
from vector with int 105.99ns 127.821 0.83 768.37ns

immediate scheduler

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no any re-schedule 1.76ns 1.24885 1.41 131.26ns
re-schedule 10 times 22.84ns 20.0581 1.14 163.62ns

just

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
just send int 91.66ns 98.7211 0.93 768.29ns
just send variadic 128.06ns 146.76 0.87 833.54ns

last

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
last construction from observable via dot + subscribe 196.28ns 271.994 0.72 427.50ns
sending of values from observable via last to subscriber 2.09ns 2.71679 0.77 1.34ns

map

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
map construction from observable via dot + subscribe 100.95ns 135.879 0.74 339.57ns
sending of values from observable via map to subscriber 1.34ns 0.957917 1.40 2.34ns

merge

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
merge 1893.27ns 2078.34 0.91 3803.49ns
merge_with 2258.24ns 2442.16 0.92 4024.17ns

observe_on

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
observe_on construction from observable via dot + subscribe 581.22ns 662.889 0.88 2820.86ns
sending of values from observable via observe_on to subscriber 87.62ns 101.835 0.86 238.77ns

publish_subject callbacks

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
on_next 22.59ns 25.3559 0.89 9.98ns
on_error 0.67ns 0.77442 0.87 16.85ns
on_completed 1.35ns 0.687971 1.96 1.01ns

publish_subject routines

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
construct 208.48ns 235.406 0.89 178.32ns
get_observable 29.47ns 35.8347 0.82 48.28ns
get_subscriber 57.82ns 60.7798 0.95 23.18ns

repeat

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
repeat construction from observable via dot + subscribe 4152.29ns 5198.74 0.80 3146.74ns

scan

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
scan construction from observable via dot + subscribe 137.34ns 174.685 0.79 382.28ns
sending of values from observable via scan to subscriber 3.02ns 3.0837 0.98 1.68ns

single-threaded locks

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no-lock increment 2.01ns 2.81317 0.71 .
mutex lock increment 18.06ns 21.4537 0.84 .
spin-lock increment 9.03ns 13.5872 0.66 .

skip

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
skip construction from observable via dot + subscribe 134.24ns 142.363 0.94 535.92ns
sending of values from observable via skip to subscriber 4.10ns 4.3867 0.94 2.35ns

switch_on_next

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
switch_on_next construction from observable via dot + subscribe 2385.44ns 2539.68 0.94 4173.90ns
sending of values from observable via switch_on_next to subscriber 599.79ns 748.162 0.80 1097.53ns

take

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take construction from observable via dot + subscribe 191.29ns 227.273 0.84 584.41ns
sending of values from observable via take to subscriber 4.24ns 5.01218 0.85 4.06ns

take_last

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take_last construction from observable via dot + subscribe 232.60ns 291.54 0.80 634.57ns
sending of values from observable via take_last to subscriber 3.73ns 4.52829 0.82 5.94ns

take_until

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take_until construction from observable via dot + subscribe 1082.23ns 1099.74 0.98 1580.52ns
sending of values from observable via take_until to subscriber 8.71ns 15.2121 0.57 1.79ns

trampoline scheduler

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no any re-schedule 21.29ns 26.7279 0.80 182.75ns
re-schedule 10 times 50.06ns 50.9557 0.98 213.39ns
recursively schedule 10 times 1448.35ns 1842.64 0.79 6570.47ns

window

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
window 2167.52ns 2600.7 0.83 3216.34ns
sending of values from observable via window to subscriber 599.47ns 679.105 0.88 415.61ns

with_latest_from

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
with_latest_from construction from observable via dot + subscribe 1129.72ns 1316.85 0.86 1370.13ns
sending of values from observable via with_latest_from to subscriber 25.46ns 29.8293 0.85 3.95ns

ci-windows

Observable construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable construction 1.33ns 1.81755 0.73 0.59ns
Dynamic observable construction 73.46ns 142.944 0.51 106.73ns
Specific observable construction + as_dynamic 71.66ns 95.9578 0.75 122.26ns

Observable lift

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable lift specific observer 154.03ns 208.863 0.74 1086.45ns
Specific observable lift dynamic observer 203.60ns 243.299 0.84 1280.20ns
Dynamic observable lift specific observer 303.31ns 363.671 0.83 1440.37ns
Dynamic observable lift dynamic observer 261.23ns 314.674 0.83 1313.35ns

Observable subscribe

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable subscribe specific observer 142.76ns 169.795 0.84 1178.42ns
Specific observable subscribe dynamic observer 132.91ns 185.809 0.72 1220.14ns
Dynamic observable subscribe specific observer 262.26ns 305.158 0.86 1209.39ns
Dynamic observable subscribe dynamic observer 203.20ns 241.571 0.84 1108.00ns

Observable subscribe #2

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observable subscribe lambda 123.02ns 165.375 0.74 1175.00ns
Dynamic observable subscribe lambda 258.77ns 334.17 0.77 1211.50ns
Specific observable subscribe lambda without subscription 139.32ns 167.681 0.83 1181.00ns
Dynamic observable subscribe lambda without subscription 228.87ns 307.109 0.75 1362.50ns
Specific observable subscribe specific subscriber 49.50ns 57.0211 0.87 740.51ns
Dynamic observable subscribe specific subscriber 146.27ns 190.327 0.77 1025.30ns
Specific observable subscribe dynamic observer 52.20ns 65.6992 0.79 876.39ns
Dynamic observable subscribe dynamic observer 101.05ns 149.151 0.68 913.81ns

Observer construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observer construction 1.50ns 1.84059 0.82 1.32ns
Dynamic observer construction 74.24ns 112.961 0.66 104.49ns
Specific observer construction + as_dynamic 73.81ns 105.094 0.70 100.30ns

OnNext

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Specific observer OnNext 0.59ns 0.802863 0.74 0.67ns
Dynamic observer OnNext 1.84ns 2.15512 0.85 2.01ns

Subscriber construction

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
Make subsriber 74.98ns 101.85 0.74 308.03ns
Make copy of subscriber 16.71ns 20.1408 0.83 27.90ns
Transform subsriber to dynamic 97.45ns 117.372 0.83 133.47ns

Subscription

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
composite_subscription create 75.07ns 111.02 0.68 340.04ns
composite_subscription add 73.58ns 86.1016 0.85 139.99ns
composite_subscription unsubscribe 72.92ns 77.7857 0.94 122.91ns

buffer

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
buffer 332.58ns 455.276 0.73 4476.00ns
sending of values from observable via buffer to subscriber 5.59ns 9.22805 0.61 82.85ns

chains creation test

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
long non-state chain creation + subscribe 249.76ns 358.132 0.70 1539.73ns
long stateful chain creation + subscribe 690.03ns 822.889 0.84 2821.43ns

combine_latest

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
combine_latest construction from observable via dot + subscribe 1423.69ns 1993.47 0.71 2648.12ns
sending of values from observable via combine_latest to subscriber 39.22ns 55.5246 0.71 3.36ns

concat

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
concat 2658.30ns 4105.89 0.65 11238.70ns
concat_with 3829.88ns 4258.33 0.90 11642.00ns

distinct_until_changed

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
distinct_until_changed construction from observable via dot + subscribe 202.37ns 241.219 0.84 904.04ns
sending of values from observable via distinct_until_changed to subscriber 2.96ns 4.03594 0.73 3.70ns

first

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
first construction from observable via dot + subscribe 148.42ns 176.336 0.84 2324.18ns
sending of values from observable via first to subscriber 2.70ns 3.23829 0.83 1.77ns

foundamental sources

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
empty 83.08ns 99.2128 0.84 2379.82ns
error 139.87ns 178.225 0.78 2466.50ns
never 51.33ns 62.3493 0.82 950.70ns

from

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
from vector with int 157.74ns 202.711 0.78 2592.90ns

immediate scheduler

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no any re-schedule 1.18ns 1.95236 0.61 413.95ns
re-schedule 10 times 87.10ns 117.324 0.74 392.62ns

just

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
just send int 78.04ns 106.267 0.73 2131.82ns
just send variadic 128.68ns 154.352 0.83 2184.80ns

last

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
last construction from observable via dot + subscribe 243.05ns 290.232 0.84 1283.88ns
sending of values from observable via last to subscriber 3.43ns 3.83825 0.89 3.02ns

map

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
map construction from observable via dot + subscribe 104.82ns 127.406 0.82 876.28ns
sending of values from observable via map to subscriber 3.83ns 5.09179 0.75 6.33ns

merge

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
merge 2627.82ns 3126.22 0.84 9622.00ns
merge_with 3394.75ns 5483.57 0.62 11712.70ns

observe_on

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
observe_on construction from observable via dot + subscribe 679.63ns 954.094 0.71 4982.20ns
sending of values from observable via observe_on to subscriber 74.63ns 112.387 0.66 740.00ns

publish_subject callbacks

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
on_next 17.48ns 23.8865 0.73 28.72ns
on_error 2.98ns 4.05827 0.73 15.99ns
on_completed 2.38ns 3.25055 0.73 0.60ns

publish_subject routines

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
construct 313.42ns 425.017 0.74 585.49ns
get_observable 25.36ns 36.7321 0.69 188.39ns
get_subscriber 50.18ns 60.2884 0.83 107.20ns

repeat

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
repeat construction from observable via dot + subscribe 5359.80ns 7304.4 0.73 9925.33ns

scan

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
scan construction from observable via dot + subscribe 181.33ns 257.932 0.70 1251.91ns
sending of values from observable via scan to subscriber 5.70ns 7.14263 0.80 7.89ns

single-threaded locks

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no-lock increment 1.66ns 2.25254 0.74 .
mutex lock increment 22.72ns 30.9019 0.74 .
spin-lock increment 9.04ns 11.0509 0.82 .

skip

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
skip construction from observable via dot + subscribe 171.14ns 231.821 0.74 1360.47ns
sending of values from observable via skip to subscriber 4.06ns 5.416 0.75 2.96ns

switch_on_next

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
switch_on_next construction from observable via dot + subscribe 3624.62ns 4282.14 0.85 10601.50ns
sending of values from observable via switch_on_next to subscriber 756.03ns 1040.1 0.73 2720.43ns

take

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take construction from observable via dot + subscribe 249.74ns 300.467 0.83 2173.58ns
sending of values from observable via take to subscriber 4.59ns 7.54457 0.61 6.14ns

take_last

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take_last construction from observable via dot + subscribe 346.65ns 418.463 0.83 2186.18ns
sending of values from observable via take_last to subscriber 4.29ns 5.12118 0.84 23.59ns

take_until

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
take_until construction from observable via dot + subscribe 1741.88ns 2088.25 0.83 4604.67ns
sending of values from observable via take_until to subscriber 11.09ns 13.3051 0.83 4.17ns

trampoline scheduler

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
no any re-schedule 16.79ns 24.2958 0.69 621.84ns
re-schedule 10 times 106.76ns 145.534 0.73 578.15ns
recursively schedule 10 times 2632.82ns 3462.4 0.76 16593.00ns

window

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
window 2955.60ns 3546.0 0.83 8560.67ns
sending of values from observable via window to subscriber 828.91ns 1002.48 0.83 1635.53ns

with_latest_from

Table
Test Name Current, ns Prev, ns Ratio RxCpp current, ns
with_latest_from construction from observable via dot + subscribe 1794.00ns 2459.83 0.73 3305.83ns
sending of values from observable via with_latest_from to subscriber 33.41ns 45.0311 0.74 6.68ns

Please sign in to comment.