RxCpp 经常调用拷贝构造函数

3

我正在尝试将RxCpp包含到我的程序中,并注意到该框架经常调用发出的对象的复制构造函数。

#include <iostream>
#include <rxcpp/rx.hpp>

class Foo
{
public:
    Foo() = default;

    Foo(Foo const &other)
    {
        std::cout << "Copy constructor called" << std::endl;
    };

    Foo(Foo &&other) noexcept
    {
        std::cout << "Move constructor called" << std::endl;
    };
};

int main()
{
    Foo bar;
    rxcpp::sources::just(std::move(bar))
            .subscribe(
                    [](Foo const &baz)
                    {
                        std::cout << "Foo received" << std::endl;
                    }
            );

    return 0;
}

运行这个命令会输出以下结果:

Move constructor called
Copy constructor called
Move constructor called
Move constructor called
Move constructor called
Move constructor called
Move constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Foo received

我首先注意到这个问题是因为我想要发布网络操作完成后创建的堆栈对象到一个主题上。在这种情况下,拷贝构造函数被调用了(仅仅?)4次,但两个操作符之间没有进行任何操作,而且这个主题只有一个订阅者。

我明白,调用拷贝构造函数是必要的,因为可能会有多个观察者在监听,并且它们不能共享移动的对象。我还预计每个可观察对象上的操作符就像另一个订阅者。

然而,我不理解为什么内部会发生如此频繁的情况,尤其是在这个例子中。这感觉像是我做错了什么。有没有一些优化的方式?同时,如果只有一个订阅者,为什么不使用移动构造函数呢?

通常使用std::shared_ptr来通过可观察对象发送大型对象以避免调用拷贝构造函数是否是一个好主意?

1个回答

2

是的,rxcpp进行了很多复制。负担在于要使值便宜易复制。

欢迎提交PR,但必须保留现有模型,其中允许每个subscribe()被调用多次。

这意味着每次调用subscribe都会创建一个订阅,并且必须为该订阅复制该值。

如果是线程上的第一个subscribe(就像在这种情况下一样),则Subscribe本身会执行额外的步骤。它使用当前线程调度程序来获取对线程的所有权。这很可能会将发送方复制到计划的工作中。这是可以节省一些副本的情况。

just()本身可能会使用指定的调度程序参数安排对on_next的调用,在本例中默认为当前线程调度程序,并使用该值进行另一份复制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接