高效的类和结构的推送

Moh*_*ana 2 c++ stl stdvector

我见过我的同事经常做第二个片段.为什么是这样?我已经尝试添加打印语句来跟踪ctors和dtors,但两者看起来都相同.

    std::vector<ClassTest> vecClass1;
    ClassTest ct1;
    ct1.blah = blah // set some stuff
    ...
    vecClass1.push_back(ct1);
Run Code Online (Sandbox Code Playgroud)

    std::vector<ClassTest> vecClass2;
    vecClass2.push_back(ClassTest());
    ClassTest& ct2 = vecClass2.back();
    ct2.blah = blah // set some stuff
    ...
Run Code Online (Sandbox Code Playgroud)

PS.如果标题有误导性,我很抱歉.

编辑:

首先,谢谢大家的回复.

我用了一个小应用程序std::move.结果让我感到惊讶,也许是因为我做错了...有人请解释为什么"快速"路径表现得更好.

#include <vector>
#include <string>
#include <boost/progress.hpp>
#include <iostream>

const std::size_t SIZE = 10*100*100*100;
//const std::size_t SIZE = 1;
const bool log = (SIZE == 1);

struct SomeType {
    std::string who;
    std::string bio;
    SomeType() {
        if (log) std::cout << "SomeType()" << std::endl;
    }
    SomeType(const SomeType& other) {
        if (log) std::cout << "SomeType(const SomeType&)" << std::endl; 
        //this->who.swap(other.who);
        //this->bio.swap(other.bio);
        this->who = other.who;
        this->bio = other.bio;
    }
    SomeType& operator=(SomeType& other) {
        if (log) std::cout << "SomeType::operator=()" << std::endl;
        this->who.swap(other.who);
        this->bio.swap(other.bio);
        return *this;
    }
    ~SomeType() {
        if (log) std::cout << "~SomeType()" << std::endl;
    }
    void swap(SomeType& other) {
        if (log) std::cout << "Swapping" << std::endl;
        this->who.swap(other.who);
        this->bio.swap(other.bio);
    }
        // move semantics
    SomeType(SomeType&& other) : 
          who(std::move(other.who))
        , bio(std::move(other.bio)) {
        if (log) std::cout << "SomeType(SomeType&&)" << std::endl;
    }
    SomeType& operator=(SomeType&& other) {
        if (log) std::cout << "SomeType::operator=(SomeType&&)" << std::endl;
        this->who = std::move(other.who);
        this->bio = std::move(other.bio);
        return *this;
    }
};

int main(int argc, char** argv) {

    {
        boost::progress_timer time_taken;
        std::vector<SomeType> store;
        std::cout << "Timing \"slow\" path" << std::endl;
        for (std::size_t i = 0; i < SIZE; ++i) {
            SomeType some;
            some.who = "bruce banner the hulk";
            some.bio = "you do not want to see me angry";
            //store.push_back(SomeType());
            //store.back().swap(some);
            store.push_back(std::move(some));
        }
    }
    {
        boost::progress_timer time_taken;
        std::vector<SomeType> store;
        std::cout << "Timing \"fast\" path" << std::endl;
        for (std::size_t i = 0; i < SIZE; ++i) {
            store.push_back(SomeType());
            SomeType& some = store.back();
            some.who = "bruce banner the hulk";
            some.bio = "you do not want to see me angry";
        }
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

dev@ubuntu-10:~/Desktop/perf_test$ g++ -Wall -O3 push_back-test.cpp -std=c++0x
dev@ubuntu-10:~/Desktop/perf_test$ ./a.out 
Timing "slow" path
3.36 s

Timing "fast" path
3.08 s
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 7

如果在"设置一些东西"之后复制对象比以前更昂贵,那么当你在"设置一些东西"而不是之后插入对象时,将对象插入向量时发生的复制将会更便宜.

但是,真的,因为你应该期望偶尔复制矢量中的对象,这可能不是一个优化.

  • 就个人而言,我是在构造函数中进行所有初始化的粉丝,在这种情况下你没有这个问题.您只需将参数传递给push_back调用中的构造函数. (2认同)