Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved C++ fastest sequential containers

    C++ Gurus
    7
    21
    8686
    Loading More Posts
    • 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.
    • Chris Kawa
      Chris Kawa Moderators last edited by Chris Kawa

      @Q139 emplace_back is not always faster. It can be faster in certain scenarios ;)

      If you have a vector of basic types (ints, floats, pointers etc.) you won't see a difference because no matter which one you use there's just gonna be a value written to memory location (probably just right from a CPU register so you can't go faster than that).

      Now for the cases it does matter. Lets say you have a big, expensive to construct or copy structure:

      struct BigStruct {
          BigStruct(int) { qDebug() << "Construction";  }
          BigStruct(const BigStruct&) { qDebug() << "Copy construction";  }
          BigStruct& operator=(const BigStruct&) { qDebug() << "Copy assignment"; return *this; }
      };
      

      Consider you push_back an element:

      std::vector<BigStruct> foo;
      foo.reserve(100);
      
      foo.push_back(BigStruct(42));
      
      // prints:
      // Construction
      // Copy construction
      

      so a temporary instance is created, copied to the vector and then destroyed.
      You might be smart and provide move semantics for your type to make it less expensive:

      struct BigStruct {
         ...
         BigStruct(BigStruct&&) { qDebug() << "Move construction";  }
         BigStruct& operator=(BigStruct&&) { qDebug() << "Move assignment"; return *this; }
      };
      

      and now you have:

      std::vector<BigStruct> foo;
      foo.reserve(100);
      
      foo.push_back(BigStruct(42));
      
      // prints:
      // Construction
      // Move construction
      

      This is better, but not all types are movable and you're still doing two things while you could be doing just one:

      std::vector<BigStruct> foo;
      foo.reserve(100);
      
      foo.emplace_back(42);
      
      // prints:
      // Construction
      

      This doesn't copy or move anything into the vector. It creates the thing already inside (usually via placement new). If the constructor takes parameters (like in this example 42) they are passed using perfect forwarding so everything is nice and optimizable.

      For a scenario a push_back is needed - that's whenever you have an item already created and you want to put it in a vector. For example a usual case:

      void SomeClass::addItem(const Item& item) {
         some_items_container.push_back(item);
      }
      

      which makes a copy of the item via copy construction.

      1 Reply Last reply Reply Quote 3
      • First post
        Last post