Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Efficiency of std::vector copy?
Forum Updated to NodeBB v4.3 + New Features

Efficiency of std::vector copy?

Scheduled Pinned Locked Moved Solved C++ Gurus
8 Posts 6 Posters 2.0k Views 6 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • fcarneyF Offline
    fcarneyF Offline
    fcarney
    wrote on last edited by fcarney
    #1

    I am working on a side project involving audio. I want to pass data around from different nodes. Some nodes may be in different threads depending upon the needs of the system. So I have settled on passing data around using signals and slots. I plan on doing things by value similar to the following:

    void sendSignal(std::vector<double> data);
    or
    struct PassData {
      std::vector<double> data;
      // other data such as sample rate, etc
    };
    void sendSignal(PassData data);
    

    Is it relatively efficient to pass data around with a vector? Is there any caveats I should be aware of? I thought about doing it by reference for speed, but then I have to maintain the original when it could be processing the next sample.

    Edit:
    I suppose QVector might be an option here due to COW as well. Not sure how it would do across threading boundaries though.

    C++ is a perfectly valid school of magic.

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      Passing an std::vector<double> around by value is basically gonna be a bunch of memcopy calls. Not a good idea if you mind performance. As for thread safety the connection itself is guarded, so both emiter and slot threads are fine, but you'd need to guarantee that nothing else is gonna modify the vector when it is being copied, so probably a mutex around the emit call and any other writing thread.

      QVector would be a lot cheaper on emit because of the implicit sharing. The connection is also safer as it only does atomic refcounting, but keep in mind that implicit sharing only guarantees container is reentrant, not thread safe, meaning you would still need a mutex around any call that causes it to detach.

      Using QVector in this scenario is pretty much like using std::shared_ptr<std::vector<double>>. Sharing is protected but access to the data is not and is up to you.

      1 Reply Last reply
      5
      • Kent-DorfmanK Offline
        Kent-DorfmanK Offline
        Kent-Dorfman
        wrote on last edited by
        #3

        As said above, it's a memcpy(), so I would use references when possible, even using a global buffer structure that is shared among threads, and locking it when appropriate with mutexes.

        1 Reply Last reply
        0
        • K Offline
          K Offline
          Konstantin Tokarev
          wrote on last edited by Konstantin Tokarev
          #4

          To avoid unnecessary copies you can use move semantics to pass vector around, e.g.

          void sendSignal(std::vector<double>&& data);
          // and use it like e.g.
          std::vector<double> data { 1.0, 2.0, 3.0 };
          sendSignal(std::move(data));
          
          1 Reply Last reply
          1
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Kent-Dorfman It's worth mentioning that using const references in cross-thread connections makes a copy anyway, so there's no gain at all in this case.

            @Konstantin-Tokarev That's risky if you have couple of slots (e.g. from different threads) connected. Only the one that happens to trigger first gets valid object.

            fcarneyF 1 Reply Last reply
            3
            • Chris KawaC Chris Kawa

              @Kent-Dorfman It's worth mentioning that using const references in cross-thread connections makes a copy anyway, so there's no gain at all in this case.

              @Konstantin-Tokarev That's risky if you have couple of slots (e.g. from different threads) connected. Only the one that happens to trigger first gets valid object.

              fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by
              #6

              @Chris-Kawa said in Efficiency of std::vector copy?:

              sing const references in cross-thread connections makes a copy anyway

              Interesting. This will affect my decision for references. I will have to play with this a bit. It really depends upon what my life cycle ends up being for each module involved. Do I pass a football around or do I copy and keep them more independent? That will be something I need to figure out.

              C++ is a perfectly valid school of magic.

              kshegunovK 1 Reply Last reply
              0
              • S Offline
                S Offline
                SimonSchroeder
                wrote on last edited by
                #7

                You should actually test which version is fastest. There are too many factors to give a definite answer. Benchmarking and profiling is always the best answer to these kind of questions. Don't optimize something that is irrelevant for the overall performance of your program. And test if there is a difference between std::vector with and without reference and QVector. Then, you will know.

                1 Reply Last reply
                1
                • fcarneyF fcarney

                  @Chris-Kawa said in Efficiency of std::vector copy?:

                  sing const references in cross-thread connections makes a copy anyway

                  Interesting. This will affect my decision for references. I will have to play with this a bit. It really depends upon what my life cycle ends up being for each module involved. Do I pass a football around or do I copy and keep them more independent? That will be something I need to figure out.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on last edited by kshegunov
                  #8

                  @fcarney said in Efficiency of std::vector copy?:

                  Interesting. This will affect my decision for references. I will have to play with this a bit. It really depends upon what my life cycle ends up being for each module involved. Do I pass a football around or do I copy and keep them more independent? That will be something I need to figure out.

                  If we are talking performance, the best would always be having a common buffer that's not locked at all (i.e. every thread working on its piece). Especially when you manage to align the pieces on the cache line size to have better cache coherency. It'd really depend on what exactly you're doing though, as for most cases the signal-slot mechanism is just fine.

                  @Chris-Kawa said in Efficiency of std::vector copy?:

                  Using QVector in this scenario is pretty much like using std::shared_ptr<std::vector<double>>. Sharing is protected but access to the data is not and is up to you.

                  Although to QVector's advantage in that case it's internally ref-counted, thus you get one indirection less accessing the underlying object (independent of syncing that actual data that is).

                  Read and abide by the Qt Code of Conduct

                  1 Reply Last reply
                  2

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved