Rx Cpp вызывает конструктор копирования много - PullRequest
1 голос
/ 01 мая 2020

Я пытаюсь включить Rx Cpp в мою программу, и я заметил, что фреймворк довольно часто вызывает конструктор копирования излучаемых объектов.

#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

Я впервые заметил это на subject, с помощью которого я хотел опубликовать sh объект, созданный в стеке после завершения сетевой операции. В этом случае конструктор копирования вызывался (только?) 4 раза, но между ними не было операторов, и у субъекта был только один подписчик.

Я понимаю, что вызов конструктора копирования необходим, поскольку несколько наблюдатели могут слушать, и они не могут разделить перемещенный объект. Я также ожидаю, что каждый оператор на наблюдаемой точно так же, как и другой подписчик.

Однако я не понимаю, почему это происходит внутри, особенно в этом примере. Такое ощущение, что я сделал что-то не так. Есть ли способ оптимизировать это? Также есть ли веская причина, по которой конструктор перемещения не используется, если имеется только один подписчик?

Как правило, целесообразно использовать std::shared_ptr для излучения больших объектов через наблюдаемое, чтобы избежать вызовов конструктора копирования?

1 Ответ

0 голосов
/ 02 мая 2020

Да, rx cpp делает много копий. Бремя лежит на стоимости, чтобы быть дешево копируемым.

PR приветствуются, но должны сохранять существующую модель, в которой каждая подписка () может вызываться несколько раз.

Это означает, что каждый вызов подписки создает подписку и должен делать копию значения для этой подписки.

Сама подписка делает дополнительный шаг, если это первая подписка в потоке (как в этом случае). Он использует текущий планировщик потока, чтобы стать владельцем потока. Это наиболее вероятно копирует отправителя в запланированную работу. Это тот случай, когда некоторые копии могут быть сохранены.

just () сам, вероятно, планирует вызов on_next, используя заданный аргумент планировщика, который по умолчанию используется текущим планировщиком потока, с другой копией значения.

...