-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix dynamic connectable #686
Conversation
📝 Walkthrough📝 WalkthroughWalkthroughThe changes in this pull request involve modifications to the Changes
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (6)
src/rpp/rpp/observables/connectable_observable.hpp (1)
Line range hint
79-91
: Add documentation for constructors.The constructors are well-implemented with proper value category handling and initialization. Consider adding documentation to describe the ownership semantics and usage patterns.
Add documentation like this:
+ /** + * @brief Constructs a connectable observable from an existing observable and subject + * @param original_observable The source observable (copied) + * @param subject The subject to connect through (shared) + */ connectable_observable(const OriginalObservable& original_observable, const Subject& subject) + /** + * @brief Constructs a connectable observable from an r-value observable and subject + * @param original_observable The source observable (moved) + * @param subject The subject to connect through (shared) + */ connectable_observable(OriginalObservable&& original_observable, const Subject& subject)src/rpp/rpp/observables/fwd.hpp (1)
175-176
: LGTM! Consider adding documentation.The forward declaration is correctly placed and follows the library's conventions. However, consider adding documentation comments to describe the purpose and usage of
dynamic_connectable_observable
, similar to how other concepts and classes in this file are documented.Add documentation in this format:
+ /** + * @brief A dynamic version of connectable_observable that allows runtime connection management + * @tparam Subject The type of the underlying subject + * @ingroup observables + */ template<typename Subject> class dynamic_connectable_observable;src/tests/rpp/test_observables.cpp (1)
112-115
: Consider documenting the move semantics test case.The test case correctly validates move construction of
dynamic_observable
. Consider adding a brief comment explaining why testing move semantics separately is important (e.g., ensuring proper resource transfer, avoiding unnecessary copies).SUBCASE("dynamic observable cast via move") { + // Explicitly test move semantics to ensure proper resource transfer test(rpp::dynamic_observable<int>{std::move(observable)}); // NOLINT }
src/tests/rpp/test_connectable_observable.cpp (1)
86-87
: LGTM: Test case properly validates dynamic conversionThe new test case effectively validates the conversion from
connectable_observable
todynamic_connectable_observable
while maintaining consistency with existing test patterns. It reuses the test lambda to ensure the converted observable behaves identically to other connectable variants.Note: There's a minor typo in "coneverted" in the test case name, but since it's just a test label and doesn't affect functionality, I'm not flagging it as an issue.
- SUBCASE("dynamic_connectable coneverted") + SUBCASE("dynamic_connectable converted")src/rpp/rpp/observables/dynamic_connectable_observable.hpp (2)
18-19
: Simplify class inheritance for improved readabilityThe inheritance statement is complex and might affect readability and maintainability. Consider introducing a type alias to simplify the base class template parameters.
Apply this diff to introduce a type alias:
+ using base_type = connectable_observable<rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>, Subject>; - class dynamic_connectable_observable final : public connectable_observable<rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>, Subject> + class dynamic_connectable_observable final : public base_type {This change improves readability by reducing the complexity of the inheritance line.
21-21
: Add an informative message to thestatic_assert
Including a custom message in the
static_assert
helps users understand the reason for the assertion failure.Apply this diff:
- static_assert(rpp::constraint::subject<Subject>); + static_assert(rpp::constraint::subject<Subject>, "Subject must satisfy the rpp::constraint::subject concept");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
src/rpp/rpp/observables/connectable_observable.hpp
(2 hunks)src/rpp/rpp/observables/dynamic_connectable_observable.hpp
(1 hunks)src/rpp/rpp/observables/dynamic_observable.hpp
(1 hunks)src/rpp/rpp/observables/fwd.hpp
(1 hunks)src/tests/rpp/test_connectable_observable.cpp
(2 hunks)src/tests/rpp/test_observables.cpp
(1 hunks)src/tests/rpp/test_observers.cpp
(1 hunks)
🔇 Additional comments (9)
src/rpp/rpp/observables/dynamic_observable.hpp (2)
66-66
: LGTM! Clean formatting change.
The vtable initialization formatting change improves readability while maintaining the same functionality.
Line range hint 1-1
: Verify removal of dynamic_connectable_observable type alias.
The AI summary indicates that the dynamic_connectable_observable
type alias was removed. Let's verify there are no remaining references to this type.
src/rpp/rpp/observables/connectable_observable.hpp (2)
72-72
: LGTM! Clean class declaration with proper type constraints.
The class declaration correctly inherits from the subject's observable type and includes appropriate type constraints.
169-176
: Verify dynamic_connectable_observable usage in the codebase.
The dynamic conversion methods are well-implemented with proper value category handling. Let's verify the usage pattern.
✅ Verification successful
Let me gather more information about the implementation and test coverage.
Dynamic connectable observable implementation and usage are properly verified
The implementation is well-tested and correctly used in the codebase:
- The
dynamic_connectable_observable
class is properly defined with value category handling - Test coverage includes both manual creation and conversion scenarios
- The implementation is used consistently with other observable patterns in the codebase
- Tests verify proper behavior with subjects, connection management, and value propagation
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify dynamic_connectable_observable usage and implementation
# Check if dynamic_connectable_observable is properly defined
rg -l "class\s+dynamic_connectable_observable"
# Check for any existing usage patterns
rg "as_dynamic_connectable\(\)" -A 3
# Verify test coverage
rg -l "test.*dynamic_connectable" "src/tests/"
Length of output: 1748
Script:
#!/bin/bash
# Check the dynamic_connectable_observable implementation
cat src/rpp/rpp/observables/dynamic_connectable_observable.hpp
# Check test coverage
cat src/tests/rpp/test_connectable_observable.cpp
Length of output: 17919
src/tests/rpp/test_observables.cpp (2)
102-106
: LGTM! Good test coverage for dynamic observable construction.
The test case properly validates the explicit construction of dynamic_observable
from a regular observable, complementing the existing dynamic observable tests.
102-115
: Verify completeness of dynamic observable test coverage.
While the current test cases cover basic functionality, let's verify if we have tests for all edge cases related to dynamic connectable observables.
✅ Verification successful
Let me analyze the test coverage for dynamic connectable observables based on the search results.
Test coverage for dynamic connectable observables is comprehensive
The test file shows thorough coverage of dynamic connectable observables including:
- Creation via manual construction
- Creation via conversion from regular connectable observable
- Testing with both finite (just) and infinite (subject) sources
- Multiple subscription scenarios
- Connection/disconnection behavior
- Value propagation
- Completion handling
- Error handling
- Multiple connect calls
- Operator chaining (map)
- Memory management (disposables)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for existing tests related to dynamic connectable observables
# and identify potential missing test cases.
# Search for dynamic connectable related tests
echo "Searching for existing dynamic connectable tests..."
rg -l "dynamic.*connectable" src/tests/
# Search for potential edge cases in implementation
echo "Searching for potential edge cases in implementation..."
rg "dynamic.*connectable.*observable" src/ --type cpp \
--glob '!tests/*' \
-A 5 -B 5
Length of output: 9232
Script:
#!/bin/bash
# Let's examine the test file content to understand the test coverage
cat src/tests/rpp/test_connectable_observable.cpp
Length of output: 15964
src/tests/rpp/test_observers.cpp (1)
191-193
: LGTM! Good test coverage for dynamic observer casting.
The added subcase completes the test matrix by verifying that explicit casting to dynamic_observer
maintains the same disposal behavior as the original observer and .as_dynamic()
conversion. This ensures consistent behavior across all ways of creating dynamic observers.
src/tests/rpp/test_connectable_observable.cpp (1)
14-14
: LGTM: Include directive properly placed
The new include for dynamic_connectable_observable.hpp is appropriately placed with related headers and follows project conventions.
src/rpp/rpp/observables/dynamic_connectable_observable.hpp (1)
25-25
: Ensure base class constructors are correctly inherited
Using using base::base;
imports all constructors from the base class. Verify that this is intentional and that it doesn't introduce unintended behaviors.
If this is intended, no action is needed.
template<rpp::constraint::observable_strategy<rpp::subjects::utils::extract_subject_type_t<Subject>> Strategy> | ||
requires (!rpp::constraint::decayed_same_as<Strategy, rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>>) | ||
dynamic_connectable_observable(const rpp::connectable_observable<Strategy, Subject>& original) | ||
: dynamic_connectable_observable{original.as_dynamic_connectable()} | ||
{ | ||
} | ||
|
||
template<rpp::constraint::observable_strategy<rpp::subjects::utils::extract_subject_type_t<Subject>> Strategy> | ||
requires (!rpp::constraint::decayed_same_as<Strategy, rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>>) | ||
dynamic_connectable_observable(rpp::connectable_observable<Strategy, Subject>&& original) | ||
: dynamic_connectable_observable{std::move(original).as_dynamic_connectable()} | ||
{ | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor constructors to eliminate code duplication
The two constructors have similar logic and can be combined to reduce duplication. Consider using a single templated constructor with perfect forwarding.
Apply this diff to refactor the constructors:
- template<rpp::constraint::observable_strategy<rpp::subjects::utils::extract_subject_type_t<Subject>> Strategy>
- requires (!rpp::constraint::decayed_same_as<Strategy, rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>>)
- dynamic_connectable_observable(const rpp::connectable_observable<Strategy, Subject>& original)
- : dynamic_connectable_observable{original.as_dynamic_connectable()}
- {
- }
-
- template<rpp::constraint::observable_strategy<rpp::subjects::utils::extract_subject_type_t<Subject>> Strategy>
- requires (!rpp::constraint::decayed_same_as<Strategy, rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>>)
- dynamic_connectable_observable(rpp::connectable_observable<Strategy, Subject>&& original)
- : dynamic_connectable_observable{std::move(original).as_dynamic_connectable()}
- {
- }
+ template<
+ rpp::constraint::observable_strategy<rpp::subjects::utils::extract_subject_type_t<Subject>> Strategy
+ >
+ requires (!rpp::constraint::decayed_same_as<Strategy, rpp::dynamic_observable<rpp::subjects::utils::extract_subject_type_t<Subject>>>)
+ dynamic_connectable_observable(rpp::connectable_observable<Strategy, Subject> original)
+ : base{std::move(original.get_observable()), original.get_subject()}
+ {
+ }
By accepting original
by value and moving it when necessary, you handle both lvalue and rvalue cases in a single constructor, reducing code duplication.
Committable suggestion skipped: line range outside the PR's diff.
BENCHMARK RESULTS (AUTOGENERATED)
|
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
Subscribe empty callbacks to empty observable | 304.65 ns | 1.85 ns | 1.85 ns | 1.00 |
Subscribe empty callbacks to empty observable via pipe operator | 303.67 ns | 1.85 ns | 1.85 ns | 1.00 |
Sources
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
from array of 1 - create + subscribe + immediate | 686.71 ns | 0.31 ns | 0.31 ns | 1.00 |
from array of 1 - create + subscribe + current_thread | 1012.26 ns | 3.42 ns | 3.42 ns | 1.00 |
concat_as_source of just(1 immediate) create + subscribe | 2227.84 ns | 111.75 ns | 113.40 ns | 0.99 |
defer from array of 1 - defer + create + subscribe + immediate | 729.16 ns | 0.31 ns | 0.31 ns | 1.00 |
interval - interval + take(3) + subscribe + immediate | 2135.23 ns | 59.19 ns | 59.19 ns | 1.00 |
interval - interval + take(3) + subscribe + current_thread | 3015.76 ns | 32.42 ns | 32.44 ns | 1.00 |
from array of 1 - create + as_blocking + subscribe + new_thread | 28416.78 ns | 27786.84 ns | 27521.43 ns | 1.01 |
from array of 1000 - create + as_blocking + subscribe + new_thread | 37580.46 ns | 49739.64 ns | 48506.54 ns | 1.03 |
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 3465.87 ns | 143.29 ns | 134.76 ns | 1.06 |
Filtering Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take(1)+subscribe | 1087.86 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+filter(true)+subscribe | 853.10 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,2)+skip(1)+subscribe | 998.36 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,1,2)+distinct_until_changed()+subscribe | 925.36 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,2)+first()+subscribe | 1230.14 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,2)+last()+subscribe | 909.56 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+take_last(1)+subscribe | 1135.51 ns | 18.52 ns | 18.53 ns | 1.00 |
immediate_just(1,2,3)+element_at(1)+subscribe | 835.13 ns | 0.31 ns | 0.31 ns | 1.00 |
Schedulers
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate scheduler create worker + schedule | 264.06 ns | 1.54 ns | 1.54 ns | 1.00 |
current_thread scheduler create worker + schedule | 478.74 ns | 4.94 ns | 4.94 ns | 1.00 |
current_thread scheduler create worker + schedule + recursive schedule | 816.73 ns | 60.98 ns | 60.98 ns | 1.00 |
Transforming Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+map(v*2)+subscribe | 832.99 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+scan(10, std::plus)+subscribe | 939.30 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+flat_map(immediate_just(v*2))+subscribe | 2395.29 ns | 174.26 ns | 144.61 ns | 1.21 |
immediate_just+buffer(2)+subscribe | 1556.12 ns | 14.21 ns | 14.20 ns | 1.00 |
immediate_just+window(2)+subscribe + subscsribe inner | 2428.24 ns | 1279.46 ns | 1335.11 ns | 0.96 |
Conditional Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take_while(false)+subscribe | 840.48 ns | - | - | 0.00 |
immediate_just+take_while(true)+subscribe | 854.51 ns | 0.31 ns | 0.31 ns | 1.00 |
Utility Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(1)+subscribe_on(immediate)+subscribe | 2254.60 ns | 0.31 ns | 0.31 ns | 1.00 |
Combining Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 3450.06 ns | 156.16 ns | 155.49 ns | 1.00 |
immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 3751.49 ns | 160.56 ns | 160.18 ns | 1.00 |
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 133.90 ns | 133.13 ns | 1.01 |
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 3662.48 ns | 401.97 ns | 455.38 ns | 0.88 |
immediate_just(1) + zip(immediate_just(2)) + subscribe | 2077.52 ns | 215.40 ns | 216.63 ns | 0.99 |
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe | 3223.88 ns | 230.63 ns | 223.79 ns | 1.03 |
Subjects
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
publish_subject with 1 observer - on_next | 34.57 ns | 14.67 ns | 14.85 ns | 0.99 |
subscribe 100 observers to publish_subject | 199616.40 ns | 15699.85 ns | 16200.72 ns | 0.97 |
100 on_next to 100 observers to publish_subject | 27406.64 ns | 17216.95 ns | 17244.61 ns | 1.00 |
Scenarios
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
basic sample | 1494.02 ns | 13.27 ns | 13.28 ns | 1.00 |
basic sample with immediate scheduler | 1528.55 ns | 5.55 ns | 5.55 ns | 1.00 |
Aggregating Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+reduce(10, std::plus)+subscribe | 917.41 ns | 0.31 ns | 0.31 ns | 1.00 |
Error Handling Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 2094.15 ns | 1005.34 ns | 1007.35 ns | 1.00 |
create(on_error())+retry(1)+subscribe | 618.46 ns | 124.72 ns | 109.61 ns | 1.14 |
ci-macos
General
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
Subscribe empty callbacks to empty observable | 972.12 ns | 0.70 ns | 2.19 ns | 0.32 |
Subscribe empty callbacks to empty observable via pipe operator | 971.09 ns | 0.70 ns | 3.21 ns | 0.22 |
Sources
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
from array of 1 - create + subscribe + immediate | 1937.96 ns | 0.23 ns | 1.19 ns | 0.20 |
from array of 1 - create + subscribe + current_thread | 2434.72 ns | 33.64 ns | 240.15 ns | 0.14 |
concat_as_source of just(1 immediate) create + subscribe | 5690.55 ns | 332.09 ns | 380.93 ns | 0.87 |
defer from array of 1 - defer + create + subscribe + immediate | 2038.78 ns | 0.24 ns | 0.28 ns | 0.88 |
interval - interval + take(3) + subscribe + immediate | 5135.78 ns | 119.43 ns | 143.68 ns | 0.83 |
interval - interval + take(3) + subscribe + current_thread | 41327.35 ns | 323.34 ns | 184.34 ns | 1.75 |
from array of 1 - create + as_blocking + subscribe + new_thread | 93416.50 ns | 89168.46 ns | 136828.33 ns | 0.65 |
from array of 1000 - create + as_blocking + subscribe + new_thread | 95520.91 ns | 95279.64 ns | 128395.89 ns | 0.74 |
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 8558.26 ns | 386.27 ns | 401.24 ns | 0.96 |
Filtering Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take(1)+subscribe | 2854.72 ns | 0.23 ns | 0.28 ns | 0.83 |
immediate_just+filter(true)+subscribe | 2123.78 ns | 0.23 ns | 0.27 ns | 0.87 |
immediate_just(1,2)+skip(1)+subscribe | 2673.14 ns | 0.24 ns | 0.29 ns | 0.80 |
immediate_just(1,1,2)+distinct_until_changed()+subscribe | 2062.00 ns | 0.46 ns | 0.55 ns | 0.83 |
immediate_just(1,2)+first()+subscribe | 3162.72 ns | 0.23 ns | 0.28 ns | 0.85 |
immediate_just(1,2)+last()+subscribe | 2341.50 ns | 0.24 ns | 0.30 ns | 0.78 |
immediate_just+take_last(1)+subscribe | 3036.63 ns | 0.23 ns | 0.27 ns | 0.86 |
immediate_just(1,2,3)+element_at(1)+subscribe | 2126.31 ns | 0.23 ns | 0.26 ns | 0.91 |
Schedulers
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate scheduler create worker + schedule | 876.30 ns | 2.50 ns | 1.26 ns | 1.98 |
current_thread scheduler create worker + schedule | 1231.30 ns | 35.57 ns | 45.01 ns | 0.79 |
current_thread scheduler create worker + schedule + recursive schedule | 2045.82 ns | 206.95 ns | 277.62 ns | 0.75 |
Transforming Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+map(v*2)+subscribe | 2689.32 ns | 19.57 ns | 5.07 ns | 3.86 |
immediate_just+scan(10, std::plus)+subscribe | 2928.28 ns | 2.38 ns | 0.51 ns | 4.66 |
immediate_just+flat_map(immediate_just(v*2))+subscribe | 5249.00 ns | 2261.26 ns | 439.91 ns | 5.14 |
immediate_just+buffer(2)+subscribe | 2489.32 ns | 63.48 ns | 77.70 ns | 0.82 |
immediate_just+window(2)+subscribe + subscsribe inner | 5383.64 ns | 2384.73 ns | 2990.38 ns | 0.80 |
Conditional Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take_while(false)+subscribe | 8709.77 ns | - | - | 0.00 |
immediate_just+take_while(true)+subscribe | 8387.95 ns | 2.27 ns | 0.27 ns | 8.32 |
Utility Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(1)+subscribe_on(immediate)+subscribe | 4863.83 ns | 4.90 ns | 5.72 ns | 0.86 |
Combining Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 7685.57 ns | 422.31 ns | 596.70 ns | 0.71 |
immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 8627.72 ns | 416.63 ns | 537.83 ns | 0.77 |
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 458.92 ns | 631.48 ns | 0.73 |
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 21145.14 ns | 964.56 ns | 1161.62 ns | 0.83 |
immediate_just(1) + zip(immediate_just(2)) + subscribe | 20240.08 ns | 1669.45 ns | 1275.03 ns | 1.31 |
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe | 7663.42 ns | 659.58 ns | 816.57 ns | 0.81 |
Subjects
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
publish_subject with 1 observer - on_next | 76.25 ns | 49.30 ns | 66.27 ns | 0.74 |
subscribe 100 observers to publish_subject | 343623.33 ns | 40414.69 ns | 48729.14 ns | 0.83 |
100 on_next to 100 observers to publish_subject | 51617.20 ns | 23450.67 ns | 27500.16 ns | 0.85 |
Scenarios
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
basic sample | 2745.94 ns | 70.01 ns | 88.94 ns | 0.79 |
basic sample with immediate scheduler | 2748.89 ns | 18.74 ns | 21.80 ns | 0.86 |
Aggregating Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+reduce(10, std::plus)+subscribe | 2368.33 ns | 0.23 ns | 0.26 ns | 0.89 |
Error Handling Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 6468.04 ns | 4035.29 ns | 4911.17 ns | 0.82 |
create(on_error())+retry(1)+subscribe | 1799.61 ns | 280.66 ns | 351.29 ns | 0.80 |
ci-ubuntu-clang
General
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
Subscribe empty callbacks to empty observable | 270.66 ns | 1.54 ns | 0.63 ns | 2.43 |
Subscribe empty callbacks to empty observable via pipe operator | 268.87 ns | 1.54 ns | 0.63 ns | 2.43 |
Sources
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
from array of 1 - create + subscribe + immediate | 570.06 ns | 0.31 ns | 0.31 ns | 1.00 |
from array of 1 - create + subscribe + current_thread | 784.31 ns | 4.01 ns | 4.01 ns | 1.00 |
concat_as_source of just(1 immediate) create + subscribe | 2457.20 ns | 129.19 ns | 128.30 ns | 1.01 |
defer from array of 1 - defer + create + subscribe + immediate | 786.05 ns | 0.31 ns | 0.31 ns | 1.00 |
interval - interval + take(3) + subscribe + immediate | 2247.49 ns | 58.31 ns | 58.31 ns | 1.00 |
interval - interval + take(3) + subscribe + current_thread | 3162.17 ns | 30.88 ns | 31.11 ns | 0.99 |
from array of 1 - create + as_blocking + subscribe + new_thread | 30178.16 ns | 28031.31 ns | 27642.74 ns | 1.01 |
from array of 1000 - create + as_blocking + subscribe + new_thread | 41766.40 ns | 39000.19 ns | 32988.93 ns | 1.18 |
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 3799.84 ns | 147.77 ns | 148.21 ns | 1.00 |
Filtering Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take(1)+subscribe | 1172.67 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+filter(true)+subscribe | 839.19 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,2)+skip(1)+subscribe | 1108.91 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,1,2)+distinct_until_changed()+subscribe | 875.42 ns | 0.62 ns | 0.62 ns | 1.00 |
immediate_just(1,2)+first()+subscribe | 1386.55 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,2)+last()+subscribe | 1019.27 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+take_last(1)+subscribe | 1215.51 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just(1,2,3)+element_at(1)+subscribe | 861.28 ns | 0.31 ns | 0.31 ns | 1.00 |
Schedulers
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate scheduler create worker + schedule | 278.81 ns | 0.63 ns | 1.54 ns | 0.41 |
current_thread scheduler create worker + schedule | 389.60 ns | 4.32 ns | 4.01 ns | 1.08 |
current_thread scheduler create worker + schedule + recursive schedule | 843.40 ns | 54.41 ns | 55.81 ns | 0.97 |
Transforming Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+map(v*2)+subscribe | 845.62 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+scan(10, std::plus)+subscribe | 976.91 ns | 0.31 ns | 0.31 ns | 1.00 |
immediate_just+flat_map(immediate_just(v*2))+subscribe | 2284.94 ns | 141.42 ns | 151.96 ns | 0.93 |
immediate_just+buffer(2)+subscribe | 1642.33 ns | 13.59 ns | 13.59 ns | 1.00 |
immediate_just+window(2)+subscribe + subscsribe inner | 2505.63 ns | 899.99 ns | 917.15 ns | 0.98 |
Conditional Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take_while(false)+subscribe | 835.40 ns | - | - | 0.00 |
immediate_just+take_while(true)+subscribe | 841.94 ns | 0.31 ns | 0.31 ns | 1.00 |
Utility Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(1)+subscribe_on(immediate)+subscribe | 2019.73 ns | 0.31 ns | 0.31 ns | 1.00 |
Combining Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 3291.16 ns | 155.67 ns | 158.54 ns | 0.98 |
immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 3743.50 ns | 137.66 ns | 140.93 ns | 0.98 |
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 141.75 ns | 142.43 ns | 1.00 |
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 3410.58 ns | 378.05 ns | 377.00 ns | 1.00 |
immediate_just(1) + zip(immediate_just(2)) + subscribe | 2235.90 ns | 201.64 ns | 195.47 ns | 1.03 |
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe | 3301.99 ns | 223.55 ns | 221.34 ns | 1.01 |
Subjects
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
publish_subject with 1 observer - on_next | 54.05 ns | 17.49 ns | 17.49 ns | 1.00 |
subscribe 100 observers to publish_subject | 206097.25 ns | 16065.66 ns | 16275.22 ns | 0.99 |
100 on_next to 100 observers to publish_subject | 47352.74 ns | 23703.80 ns | 23638.56 ns | 1.00 |
Scenarios
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
basic sample | 1301.52 ns | 11.42 ns | 11.43 ns | 1.00 |
basic sample with immediate scheduler | 1292.76 ns | 5.86 ns | 5.86 ns | 1.00 |
Aggregating Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+reduce(10, std::plus)+subscribe | 1008.34 ns | 0.31 ns | 0.31 ns | 1.00 |
Error Handling Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 2210.84 ns | 1162.13 ns | 1179.24 ns | 0.99 |
create(on_error())+retry(1)+subscribe | 651.88 ns | 140.01 ns | 140.04 ns | 1.00 |
ci-windows
General
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
Subscribe empty callbacks to empty observable | 571.27 ns | 1.85 ns | 2.16 ns | 0.86 |
Subscribe empty callbacks to empty observable via pipe operator | 585.46 ns | 1.85 ns | 2.16 ns | 0.86 |
Sources
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
from array of 1 - create + subscribe + immediate | 1148.93 ns | 5.55 ns | 5.55 ns | 1.00 |
from array of 1 - create + subscribe + current_thread | 1425.45 ns | 15.44 ns | 15.46 ns | 1.00 |
concat_as_source of just(1 immediate) create + subscribe | 3702.46 ns | 168.75 ns | 169.03 ns | 1.00 |
defer from array of 1 - defer + create + subscribe + immediate | 1186.25 ns | 5.55 ns | 5.55 ns | 1.00 |
interval - interval + take(3) + subscribe + immediate | 3337.78 ns | 141.01 ns | 139.75 ns | 1.01 |
interval - interval + take(3) + subscribe + current_thread | 3388.48 ns | 60.95 ns | 59.79 ns | 1.02 |
from array of 1 - create + as_blocking + subscribe + new_thread | 122477.78 ns | 113120.00 ns | 114333.33 ns | 0.99 |
from array of 1000 - create + as_blocking + subscribe + new_thread | 128900.00 ns | 137537.50 ns | 127711.11 ns | 1.08 |
concat_as_source of just(1 immediate) and just(1,2 immediate)create + subscribe | 5370.51 ns | 199.48 ns | 196.17 ns | 1.02 |
Filtering Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take(1)+subscribe | 1806.52 ns | 19.73 ns | 19.42 ns | 1.02 |
immediate_just+filter(true)+subscribe | 1622.05 ns | 18.81 ns | 18.51 ns | 1.02 |
immediate_just(1,2)+skip(1)+subscribe | 1730.32 ns | 18.50 ns | 17.90 ns | 1.03 |
immediate_just(1,1,2)+distinct_until_changed()+subscribe | 1359.50 ns | 23.46 ns | 20.88 ns | 1.12 |
immediate_just(1,2)+first()+subscribe | 2372.86 ns | 17.28 ns | 18.21 ns | 0.95 |
immediate_just(1,2)+last()+subscribe | 1469.53 ns | 18.50 ns | 19.14 ns | 0.97 |
immediate_just+take_last(1)+subscribe | 2007.10 ns | 64.67 ns | 64.94 ns | 1.00 |
immediate_just(1,2,3)+element_at(1)+subscribe | 1641.22 ns | 21.94 ns | 22.07 ns | 0.99 |
Schedulers
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate scheduler create worker + schedule | 475.27 ns | 4.32 ns | 4.32 ns | 1.00 |
current_thread scheduler create worker + schedule | 645.95 ns | 11.11 ns | 11.12 ns | 1.00 |
current_thread scheduler create worker + schedule + recursive schedule | 1338.85 ns | 98.73 ns | 99.33 ns | 0.99 |
Transforming Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+map(v*2)+subscribe | 1320.05 ns | 18.81 ns | 18.82 ns | 1.00 |
immediate_just+scan(10, std::plus)+subscribe | 1438.85 ns | 21.27 ns | 20.96 ns | 1.01 |
immediate_just+flat_map(immediate_just(v*2))+subscribe | 3850.50 ns | 179.45 ns | 185.40 ns | 0.97 |
immediate_just+buffer(2)+subscribe | 2314.62 ns | 63.56 ns | 64.10 ns | 0.99 |
immediate_just+window(2)+subscribe + subscsribe inner | 4009.00 ns | 1290.08 ns | 1277.56 ns | 1.01 |
Conditional Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+take_while(false)+subscribe | 1322.44 ns | 17.57 ns | 17.58 ns | 1.00 |
immediate_just+take_while(true)+subscribe | 1325.75 ns | 18.81 ns | 18.51 ns | 1.02 |
Utility Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(1)+subscribe_on(immediate)+subscribe | 3232.71 ns | 11.10 ns | 11.10 ns | 1.00 |
Combining Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just(immediate_just(1), immediate_just(1)) + merge() + subscribe | 5349.78 ns | 203.85 ns | 198.78 ns | 1.03 |
immediate_just(1) + merge_with(immediate_just(2)) + subscribe | 5705.32 ns | 181.20 ns | 185.01 ns | 0.98 |
immediate_just(1) + with_latest_from(immediate_just(2)) + subscribe | - | 192.99 ns | 194.19 ns | 0.99 |
immediate_just(immediate_just(1),immediate_just(1)) + switch_on_next() + subscribe | 6126.90 ns | 445.48 ns | 452.48 ns | 0.98 |
immediate_just(1) + zip(immediate_just(2)) + subscribe | 3884.69 ns | 520.22 ns | 520.52 ns | 1.00 |
immediate_just(immediate_just(1), immediate_just(1)) + concat() + subscribe | 4951.90 ns | 335.53 ns | 316.50 ns | 1.06 |
Subjects
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
publish_subject with 1 observer - on_next | 35.98 ns | 20.13 ns | 20.35 ns | 0.99 |
subscribe 100 observers to publish_subject | 261120.00 ns | 28116.67 ns | 27592.68 ns | 1.02 |
100 on_next to 100 observers to publish_subject | 55036.84 ns | 32600.00 ns | 32596.77 ns | 1.00 |
Scenarios
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
basic sample | 1920.63 ns | 101.08 ns | 95.54 ns | 1.06 |
basic sample with immediate scheduler | 1923.79 ns | 74.87 ns | 68.25 ns | 1.10 |
Aggregating Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
immediate_just+reduce(10, std::plus)+subscribe | 1465.60 ns | 19.42 ns | 19.13 ns | 1.02 |
Error Handling Operators
name | rxcpp | rpp | prev rpp | ratio |
---|---|---|---|---|
create(on_next(1), on_error())+on_error_resume_next(immediate_just(2)))+subscribe | 1926.73 ns | 357.76 ns | 356.91 ns | 1.00 |
create(on_error())+retry(1)+subscribe | 1558.69 ns | 137.50 ns | 137.33 ns | 1.00 |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## v2 #686 +/- ##
=======================================
Coverage 98.60% 98.61%
=======================================
Files 155 156 +1
Lines 9775 9787 +12
=======================================
+ Hits 9639 9651 +12
Misses 136 136 ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
Quality Gate passedIssues Measures |
Summary by CodeRabbit
New Features
dynamic_connectable_observable
class for enhanced dynamic behavior in observables.connectable_observable
instances todynamic_connectable_observable
.Bug Fixes
Subject
provision inconnectable_observable
constructors.Tests
dynamic_connectable_observable
and enhanced existing tests for observables and observers to ensure robust validation of dynamic behavior.